很激动,竟然有人看我的文章
首先感谢liuyubobobo的代码,
点击打开链接
我决定好好把堆这一块的知识再补充一下
堆的三个要点:
①建堆——从第一个非叶子节点开始,从后往前,将每一个小堆都变成最大堆(这是一个和孩子比较大小的过程,shiftDown)
②插入堆——这是一个和父节点比较大小的过程(shiftUp)
③pop堆——将当前堆的第一个元素和最后一个元素交换位置,然后对剩下的n-1个重新建堆(shiftDown)
template<typename Item> class MaxHeap { private: Item* data; //堆的数组 int count; //堆中元素的个数 int capacity; //堆的容量 void shiftUp(int k) { while (k>1 && data[k / 2] < data[k]) { swap(data[k / 2], data[k]); k /= 2; } } void shiftDown(int k) { while (2 * k <= count) { int j = 2 * k; if (j + 1 <= count&& data[j + 1] > data[j]) j = j + 1; if (data[k] > data[j]) break; //可以优化的点 swap(data[k], data[j]); k = j; } } public: MaxHeap(int capacity) { data = new Item[capacity + 1]; count = 0; this->capacity = capacity; } MaxHeap(Item arr[], int n) { //建堆 data = new Item[n + 1]; capacity = n; for (int i = 0; i < n; i++) data[i + 1] = arr[i]; count = n; for (int i = count / 2; i >= 1; i--) shiftDown(i); } ~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; } };