首先介绍一下堆,它是一种经过排序的完全二叉树,其中任一非叶子节点的大小都不大于(或不小于)其左右儿子的值。
最小堆:即任一非叶子节点的值都不大于其左右孩子的值,一个最小堆如下图:
首先介绍最小堆的插入操作,
void push(int e)
{
int s=size++;
shitup(s,e);
}///最小堆元素的放入
void shitup(int s,int e)
{
while(s>0)
{
int parent=(s-1)/2;
if(e>Heap[parent])
{
break;
}
Heap[s]=Heap[parent];
s=parent;
}
Heap[s]=e;
}///给堆中加入元素
void shitdown(int s,int e
先每次在数组的最后位置加一个新的位置,size值加1,执行插入时,由这个新的位置往上找,找到一个要添加的元素比该位置的父节点要大的位置,然后这个位置即是新元素的位置。在讯位置的同时不断把不合条件的点往下移,这样维护了最小堆的结构特点。
最小堆的元素出堆操作:
int pop()
{
if(size<=0)
{
return -1;
}
int ret=Heap[0];
int s=--size;
shitdown(0,Heap[s]);
Heap[s]=0;
return ret;
}///数据出堆
void shitdown(int s,int e)
{
int half=size/2;
while(s<half){
int child=s*2+1;
int right=child+1;
if(right<size&&Heap[child]>Heap[right]){
child=right;
}
if(e<Heap[child]){
break;
}
Heap[s]=Heap[child];
s=child;
}
Heap[s]=e;
}///将堆中的元素删除
数据出堆操作是这样子的,把根节点元素取出,元素个数减1,然后调整堆的结构,从删除的元素的位置开始,不断寻找儿子节点来代替该节点,若发现数组最后一个元素比该节点的两个儿子的值都小,则把该元素放入该位置。最后整过程就这样子了。
最大堆:既然知道了最小堆,那么最大堆和最小堆都一样,就是符号不同而已