資料結構 最小堆的類模板實現

2021-07-04 05:32:23 字數 2773 閱讀 8104

堆資料結構是一種陣列物件,它可以被視為一科完全二叉樹結構。

它的特點是父節點的值大於(小於)兩個子節點的值(分別稱為最大堆和最小堆)。它常用於管理演算法執行過程中的資訊,應用場景包括堆排序,優先佇列等。1

、根結點若有子樹,則子樹一定也是堆。

2、根結點一定大於(或小於)子結點。

因為要求堆必須是完全二叉樹,所以可以用線性的資料結構,比如陣列,來實現堆。

利用陣列實現,則對於長為

n的堆中的元素從0到

n-1排列,有:

i的父結點:

parent(i)=(i+1)/2-1

i的左葉子:

left(i)=(i+1)*2-1

i的右葉子:

right(i)=(i+1)*2

堆(heap),其實也沒什麼大不了,簡單地說就是一種有序佇列而已,普通的佇列是先入先出,而二叉堆是:最小先出。

這不是很簡單麼?如果這個佇列是用陣列實現的話那用打擂台的方式從頭到尾找一遍,把最小的拿出來不就行了?行啊,可是出隊的操作是很頻繁的,而每次都得打一遍擂台,那就低效了,打擂台的時間複雜度為ο(n),那如何不用從頭到尾fetch一遍就出隊呢?二叉堆能比較好地解決這個問題,不過之前先介紹一些概念。

完全樹(complete tree):從下圖中看出,在第n層深度被填滿之前,不會開始填第n+1層深度,還有一定是從左往右填滿。

這樣有什麼好處呢?好處就是能方便地把指標省略掉,用乙個簡單的陣列來表示一棵樹,如圖:

那麼下面介紹二叉堆:二叉堆是一種完全二叉樹,其任意子樹的左右節點(如果有的話)的鍵值一定比根節點大,上圖其實就是乙個二叉堆。

你一定發覺了,最小的乙個元素就是陣列第乙個元素,那麼二叉堆這種有序佇列如何入隊呢?看圖:

假設要在這個二叉堆裡入隊乙個單元,鍵值為2,那只需在陣列末尾加入這個元素,然後盡可能把這個元素往上挪,直到挪不動,經過了這種複雜度為ο(logn)的操作,二叉堆還是二叉堆。

那如何出隊呢?也不難,看圖:

將最小的節點刪除後,把最後的乙個節點放到第乙個節點的位置,然後在調整。

最小堆的類模板實現:類介面部分

/

#include using namespace std;

#define defaultsize 10

templateclass minheap //最小堆的類模板實現

bool isempty()const

bool isfull()const

void makeempty()

bool insert(const t& x); //在陣列尾部插入,並調整堆

bool removemin(t& x); //刪除堆頂上的最小元素,最後乙個元素補到堆頂,然後調整

private:

t * heap; //採用陣列作為其儲存方式。

int currentsize;

int maxheapsize;

void siftdown(int start, int m);//從start到m下滑調整為最小堆

void siftup(int start); //從start到0上滑調整為最小堆

};

具體介面函式實現部分:

templateminheap::minheap(int sz=defaultsize)

}templatevoid minheap::siftdown(int start, int m)//堆的下滑調整演算法,從節點start到m為止,從上到下比較,如果子女小於父節點,

heap[j]=temp;

}}templatebool minheap::insert(const t& x)

heap[currentsize]=x;

siftup(currentsize);

++currentsize;

return true;

}templatebool minheap::removemin(t& x)

x=heap[0];

heap[0]=heap[currentsize-1];

--currentsize;

siftdown(0,currentsize-1);

return true;

}

驗證程式:

為了簡單,驗證時把類中private遮蔽掉,以便外面訪問;

int main(int argc, char* argv)

; int i=0;

while(ih(arr,sizeof(arr)/sizeof(arr[0]));

i=0;

while(i<6){

cout<

5 4 3 2 1 0

0 1 3 2 4 5

0 1 3 2 4 5 10

1 2 3 10 4 5

請按任意鍵繼續. . .

資料結構 類模板實現鍊錶

鍊錶節點 templateclass linknode 鍊錶 templateclass linklist 指定位置插入 void inset linklist int pos,t data 建立新的節點 linknode newnode new linknode newnode data data...

6 資料結構 最小堆

開發過程,經常需要對資料集合進行維護。維護資料結合的資料結構可統稱為容器。最小堆是維護資料集合的容器的一種,最小堆具備如下性質 設v i 為位置i的元素值 1.對維護的n個元素,順序儲存於索引為1 n的陣列位置 2.對索引i,若索引2 i n,有v i v 2 i 若索引2 i 1 n,有v i v...

C 資料結構之最小堆的實現方法

最小堆 基本思想 堆對應一棵完全二叉樹,且所有非葉結點的值均不大於 或不小於 其子女的值,根結點 堆頂元素 的值是最小 或最大 的,每次都取堆頂的元素,將其放在序列最後面,然後將剩餘的元素重新調整為最小 大 堆,依次類推,最終得到排序的序列。堆排序分為大頂堆和小頂堆排序。大頂堆 堆對應一棵完全二叉樹...