【模板】堆的结构
這里是最小堆,最大堆也是類似的。
1.堆是一顆完全二叉樹。
性質(zhì):子節(jié)點的值一定不小于父節(jié)點的值。
堆的存儲用一個數(shù)組heap[n]即可。
由于完全二叉樹的性質(zhì),節(jié)點是按順序排列的,
i 節(jié)點的子節(jié)點編號為 2i+1 和 2i+2 。
同理 i 節(jié)點的父節(jié)點為 (i-1)/2 。
操作:堆有插入和刪除兩種操作,由于是二叉樹,兩種操作都是O(logn) 的 。
實現(xiàn)C++代碼:
#include <bits\stdc++.h> using namespace std; #define MAX_N 1000int heap[MAX_N],sz = 0;void push(int x){//新加入節(jié)點的編號 int i = sz++;while(i > 0){//父節(jié)點 int p = (i-1)/2;//如果新加節(jié)點小于它的父節(jié)點,則退出 if(heap[p] <= x) break;//把父節(jié)點放下來 heap[i] = heap[p];//把自己提上去 i = p;}//循環(huán)退出的時候已經(jīng)找到了該放的位置 // 把新節(jié)點加入進來 heap[i] = x; }int pop(){//有值才能pop assert(sz > 0);//要刪除的元素 int ret = heap[0];//記錄最后一個節(jié)點的值 int x = heap[--sz];//找到最后一個節(jié)點該待的位置,因為最后一個節(jié)點已經(jīng)被刪除了 int i = 0;//如果有子節(jié)點就循環(huán) while(i * 2 + 1 < sz){//找到較小的子節(jié)點 int a = i*2+1;int b = i*2+2;if(b < sz&&heap[b] < heap[a]) a = b;//如果較小的子節(jié)點大于最后一個節(jié)點的值則退出,因為已經(jīng)找到了最后一個節(jié)點該待的位置 if(heap[a] >= x) break;//把子節(jié)點提上來 heap[i] = heap[a]; //進入子節(jié)點 i = a; }//把最后一個節(jié)點放到它該待的位置 heap[i] = x;return ret; } int main(){}總結(jié)
- 上一篇: 新疆大学OJ(ACM) 1099: 数列
- 下一篇: 【算法】二分图的判定