二叉堆

//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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值