堆資料結構是一種陣列物件,它可以被視為一科完全二叉樹結構。
它的特點是父節點的值大於(小於)兩個子節點的值(分別稱為最大堆和最小堆)。它常用於管理演算法執行過程中的資訊,應用場景包括堆排序,優先佇列等。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 資料結構之最小堆的實現方法
最小堆 基本思想 堆對應一棵完全二叉樹,且所有非葉結點的值均不大於 或不小於 其子女的值,根結點 堆頂元素 的值是最小 或最大 的,每次都取堆頂的元素,將其放在序列最後面,然後將剩餘的元素重新調整為最小 大 堆,依次類推,最終得到排序的序列。堆排序分為大頂堆和小頂堆排序。大頂堆 堆對應一棵完全二叉樹...