標籤:方式 nbsp 二叉樹 完全二叉樹 增加 擴容 i++ 函數 max
heap並不屬於STL容器組件,它分為 max heap 和min heap,在預設情況下,max-heap是優先隊列(priority queue)的底層實現機制。
而這個實現機制中的max-heap實際上是以一個vector表現的完全二叉樹(complete binary tree)。
二元堆積(binary heap)就是i一種完全二叉樹。也即是。整棵二叉樹除了最底層的分葉節點以外,都是填滿的,而最低層的葉子結點必須是從左至右不留空隙。
至於max-heap和min-heap,前者的任何一個父親結點都必須大於等於他的任意子結點,而後者相反。
《在這裡值得一提的是》,heap對於map/unordered_map的排序(大小排序方式)是根據key值來排序的。
操作:
push_heap():新添加一個元素在末尾,然後重新調整堆序。也就是把元素添加在底層vector的end()處。
該演算法必須是在一個已經滿足堆序的條件下,添加元素。該函數接受兩個隨機迭代器,分別表示first,end,區間範圍。
關鍵是我們執行一個siftup()函數,上溯函數來重新調整堆序。
pop_heap()這個演算法跟push_heap類似,參數一樣。不同的是我們把堆頂元素取出來,放到了數組或者是vector的末尾,用原來末尾元素去替代,然後end迭代器減1,執行siftdown()下溯函數來重新調整堆序。
注意演算法執行完畢後,最大的元素並沒有被取走,而是放於底層容器的末尾。如果要取走,則可以使用底部容器(vector)提供的pop_back()函數。
sort_heap()演算法:既然每次pop_heap可以獲得堆中最大的元素,那麼我們持續對整個heap做pop_heap操作,每次將操作的範圍向前縮減一個元素。
sort_heap() 演算法:接受兩個隨機迭代器作為參數。表示操作的範圍。
make_heap()演算法:建立一個堆。很簡單吧。接受的參數同上。
#include <iostream>#include <algorithm> // make_heap(), pop_heap(), push_heap()#include <vector>using namespace std;void printVector(vector<int> &num){ for(int i = 0; i < num.size(); i++) cout<<num[i]<<" "; cout<<endl;}int main(){ // init int arr[] = {5,1,6,9,4,3}; vector<int> num(arr,arr+6); printVector(num); // build make_heap(num.begin(),num.end()); printVector(num); // 9 5 6 1 4 3 預設大頂堆 // get the biggest number // 從vector的角度來取得 cout<<num[0]<<endl; // 9 // or num.front(); cout<<num.front()<<endl; // 9 // delete 堆頂,即最大的元素 // 傳回值為 void // 將堆頂的元素放到最後一個位置上 // 彈出一個元素後,剩下的又重建了 heap,仍保持heap的性質 pop_heap(num.begin(),num.end()); printVector(num); // 6 5 3 1 4 9 // vector 刪除末尾元素 num.pop_back(); printVector(num); num.push_back(7); //首先在vector上擴容,增加一個元素到尾部 printVector(num); // 6 5 3 1 4 7 push_heap(num.begin(),num.end()); // 指定區間的最後一個元素加入堆中並使整個區間成為一個新的堆。注意前提是最後一個元素除外的所有元素已經構成一個堆。 printVector(num); // 7 5 6 1 4 3 // 判斷是否為堆 bool ret = is_heap(num.begin(),num.end()); cout<<ret<<endl; num.push_back(9); printVector(num); // 7 5 6 1 4 3 9 cout<< is_heap(num.begin(),num.end()) <<endl; push_heap(num.begin(),num.end()); printVector(num); // 9 5 7 1 4 3 6 sort_heap(num.begin(),num.end()); printVector(num); // 1 3 4 5 6 7 9} // 小頂堆#include <iostream>#include <vector>#include <algorithm>using namespace std;class greater_class{public: bool operator()(int a, int b) { return a > b; }};int main(){ // init int arr[] = {5,1,6,9,4,3}; vector<int> num(arr,arr+6); printVector(num); make_heap(num.begin(), num.end(), greater_class()); printVector(num); // 1 4 3 9 5 6 num.push_back(2); printVector(num); // 1 4 3 9 5 6 2 push_heap(num.begin(),num.end(),greater_class()); printVector(num); // 1 4 2 9 5 6 3 while (num.size()) { pop_heap(num.begin(),num.end(),greater_class()); long min = num.back(); num.pop_back(); cout << min << std::endl; } // 1 2 3 4 5 6 9}
c++ heap學習