很激动,竟然有人看我的文章
首先感谢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;
}
};