堆分为小根堆和大根堆。小根堆是一棵完全二叉树,并且
根节点的值小于左孩子和右孩子的值,而且它们是递归定义的,就是左右孩子又分别是小根堆。
struct HeapSq{
ElemType* heap;
int len;
int MaxSize;
};
初始化堆
void InitHeap(struct HeapSq* HBT,int MS)
{
if(MS<=0){
printf("MS is not valid!\n");
exit(1);
}
清除堆
void ClearHeap(struct HeapSq* HBT)
{
if(HBT->heap!=NULL){
free(HBT->heap);
HBT->heap=NULL:
HBT->len=0;
HBT->MaxSize=0;
}
}
检查一个堆是否为空
int EmptyHeap(struct HeapSq* HBT)
{
if(HBT->len==0)return 1;else return 0;
}
向堆中插入一个元素
先在堆的末尾加入元素,然后根父节点记性对比,如果比父节点小,就上升,并循环下去。
void InsertHeap(struct HeapSq* HBT,ElemType x)
{
int i;
if(HBT->len==HBT->MaxSize){
ElemType *p;
p=realloc(HBT->heap,2*HBT->MaxSize*sizeof(ElemType));
if(!p){
printf("realloc failed!\n");
exit(1);
}
HBT->heap=p;
HBT->MaxSize=2*HBT->MaxSize;
}
HBT->heap[HBT->len]=x;
HBT->len++;
i=HBT->len-1;
while(i!=0){
int j=(i-1)/2;
if(x>=HBT->heap[j])break;
HBT->heap[i]=HBT->heap[j];
i=j;
}
HBT->heap[i]=x;
}
从堆中删除元素
从堆中删除堆顶元素,留下的位置由堆尾元素填补,然后跟左右孩子对比,并与较小的孩子交换,循环下去,使其保持最小堆的特性。
ElemType DeleteHeap(struct HeapSq* HBT)
{
ElemType temp,x;
int i,j;
if(HBT->len=0){
printf("heap is empty!\n");
exit(1);
}
temp=HBT->heap[0];
HBT->len--;
if(HBT->len==0)return temp;
x=HBT->heap[HBT->len];
i=0;
j=2*i+1;
while(j<=HBT->len-1){
if(j<HBT->len-1&&HBT->heap[j]>HBT->heap[j+1])j++;
if(x<=HBT->heap[j])break;
HBT->heap[i]=HBT->heap[j];
i=j;j=2*i+1;
}
HBT->heap[i]=x;
return temp;
}