#include <iostream> #include <cassert> #include <ctime> using namespace std; /** 一句箴言: 堆老是一棵徹底二叉樹,堆中某一節點的值老是不大於其父節點的值, 插入節點使用shiftUp,取出最大值(根節點)後須要使用 shiftDown向下整理 方法: 變更後使用遞歸或者循環的方式,按照堆的定義進行值的互換調整便可 **/ template<typename Item> class MaxHeap { private: Item* data; int count; int capacity; //從堆中取出第一個元素後,用最後一個元素替換後,自頂向下進行調整 void shiftDown(int k) { while(2*k <= count) { int j = 2*k; if (j + 1 <= count && data[j+1] > data[j]) { j+=1; } if (data[k] >= data[j]) { break; } swap(data[k], data[j]); k=j; } /** //下面爲遞歸寫法 if (2 * k > count) { return; } int j = 2*k; if (j+1 <=count && data[j] < data[j+1]) { j = j+1; } swap(data[k], data[j]); shiftDown(j); **/ } // 從堆最後插入元素後進行自底向上調整 void shiftUp(int k) { while(k > 1 && data[k/2] < data[k]) { swap(data[k/2], data[k]); k = k/2; } /** //下面爲遞歸寫法 if (k > 1 && data[k/2] < data[k]) { swap(data[k/2] , data[k]); k = k/2; shiftUp(k); } **/ } public: MaxHeap(int capacity) { data = new Item[capacity+1]; this->capacity = capacity; count = 0; } ~MaxHeap() { delete [] data; } int size() { return count; } bool isEmpty() { return count == 0; } //從堆尾插入元素並向上調整使其保持堆結構 void insert(Item item) { assert(count +1 <= capacity); data[count+1] = item; count++; shiftUp(count); } //從堆頭取出最大元素 Item extractMax() { assert(count>0); Item ret = data[1]; swap(data[1], data[count]); count--; shiftDown(1); return ret; } void printData() { for(int i =1; i<=count; i++) { cout<<data[i] << " "; } } }; int main() { MaxHeap<int> maxheap = MaxHeap<int>(100); srand(time(NULL)); for (int i =0; i<5; i++) { int tmp = rand()%10; maxheap.insert(tmp); cout<<tmp << " "; } cout<<endl; maxheap.printData(); maxheap.extractMax(); cout<<endl; maxheap.printData(); maxheap.extractMax(); cout<<endl; maxheap.printData(); return 0; }