//Binary Heap,the most common implement of Poriority Queen(Heap)
//以最小堆为例
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct heapNode{
int capacity;
int size;
int *data;
};
struct heapNode* Init(struct heapNode* binaryHeap,int n)//初始化
{
binaryHeap=(struct heapNode*)malloc(sizeof(struct heapNode));
binaryHeap->capacity=n;
binaryHeap->size=0;
binaryHeap->data=(int*)malloc(sizeof(int)*(n+1));
binaryHeap->data[0]=-10000;
return binaryHeap;
}
void Destory(struct heapNode* binaryHeap)//释放
{
free(binaryHeap->data);
free(binaryHeap);
return;
}
int IsEmpty(struct heapNode *binaryHeap)//判断堆空不空
{
return binaryHeap->size==0;
}
int IsFull(struct heapNode* binaryHeap)//判断堆满不满
{
return binaryHeap->size==binaryHeap->capacity;
}
void Insert(struct heapNode* binaryHeap,int number)//插入
{
int i;
if(!IsFull(binaryHeap)){
binaryHeap->size++;
//percolated up 上滤
for(i=binaryHeap->size;i>1&&binaryHeap->data[i/2]>number;i/=2)
binaryHeap->data[i]=binaryHeap->data[i/2];
binaryHeap->data[i]=number;
}
return;
}
void DeleteMin(struct heapNode* binaryHeap)//删除最小
{
int i,child;
int minElement;
int lastElement;
if(!IsEmpty(binaryHeap)){
//minElement=binaryHeap->data[1];
if(binaryHeap->size==1){
binaryHeap->size--;
return;
}
lastElement=binaryHeap->data[binaryHeap->size--];
//percolated down 下滤
for(i=1;i*2<=binaryHeap->size;i=child){//此处用i*2判断很重要
child=i*2;
if(child!=binaryHeap->size&&binaryHeap->data[child+1]<binaryHeap->data[child])
child++;
if(lastElement>binaryHeap->data[child])
binaryHeap->data[i]=binaryHeap->data[child];
else
break;
}
binaryHeap->data[i]=lastElement;
return;
}
return;
}
void BuildHeap(struct heapNode* binaryHeap)//建堆
{
int n,temp,child,j;
scanf("%d",&n);
if(n>binaryHeap->capacity)
return;
for(int i=1;i<=n;i++)
scanf("%d",&(binaryHeap->data[++binaryHeap->size]));
for(int i=binaryHeap->size/2;i>=1;i--){//逐一下滤
temp=binaryHeap->data[i];
for(j=i;j*2<=binaryHeap->size;j=child){//此处用j*2判断很重要
child=2*j;
if(child!=binaryHeap->size&&binaryHeap->data[child+1]<binaryHeap->data[child])
child=child+1;
if(temp>binaryHeap->data[child])
binaryHeap->data[j]=binaryHeap->data[child];
else
break;
}
binaryHeap->data[j]=temp;
}
return;
}
void Delete(struct heapNode* binaryHeap,int loc)//删除某个节点的值
{
int i,number;
if(loc<=0||loc>binaryHeap->size)
return;
//先把此处的值变为近似无限小
binaryHeap->data[loc]=-100000000;
number=binaryHeap->data[loc];
//上滤
for(i=loc;i>1&&number<binaryHeap->data[i/2];i--)
binaryHeap->data[i]=binaryHeap->data[i/2];
binaryHeap->data[i]=number;
//删除目前位于1处的节点
DeleteMin(binaryHeap);
return;
}
void IncreaseKey(struct heapNode* binaryHeap,int loc,int increasement)//增加某个节点的键值
{
int i,number,child;
if(loc<=0||loc>binaryHeap->size||increasement<=0)
return;
binaryHeap->data[loc]+=increasement;
//下滤
number=binaryHeap->data[loc];
for(i=1;i*2<=binaryHeap->size;i=child){//此处用i*2判断很重要
child=i*2;
if(child!=binaryHeap->size&&binaryHeap->data[child+1]<binaryHeap->data[child])
child++;
if(number>binaryHeap->data[child])
binaryHeap->data[i]=binaryHeap->data[child];
else
break;
}
binaryHeap->data[i]=number;
return;
}
void DecreaseKey(struct heapNode* binaryHeap,int loc,int decreasement)//减少某个节点的键值 假设decreasement为正
{
int i,number,child;
if(loc<=0||loc>binaryHeap->size||decreasement<=0)
return;
binaryHeap->data[loc]-=decreasement;
//上滤
number=binaryHeap->data[loc];
for(i=loc;i>=1&&binaryHeap->data[i/2]>number;i/=2)
binaryHeap->data[i]=binaryHeap->data[i/2];
binaryHeap->data[i]=number;
return;
}
void levelOrderTrversal(struct heapNode* binaryHeap)//按照节点编号打印节点数值
{
for(int i=1;i<=binaryHeap->size;i++)
printf("%d:%d%c",i,binaryHeap->data[i],i==binaryHeap->size?'\n':' ');
return;
}
int main(){
struct heapNode *binaryHeap;
binaryHeap=Init(binaryHeap,100);
BuildHeap(binaryHeap);
levelOrderTrversal(binaryHeap);
Insert(binaryHeap,10);
levelOrderTrversal(binaryHeap);
DeleteMin(binaryHeap);
levelOrderTrversal(binaryHeap);
Delete(binaryHeap,2);
levelOrderTrversal(binaryHeap);
IncreaseKey(binaryHeap,1,7);
levelOrderTrversal(binaryHeap);
DecreaseKey(binaryHeap,3,7);
levelOrderTrversal(binaryHeap);
return 0;
}