#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; }