堆的操作

堆是一个优先队列;取出元素的顺序是依照优先值大小;
堆是一个用数组存储的完全二叉树,任何一个节点是其子树的所有节点的最大值(最小值);

堆的结构

typedef struct Node* Heap;
#define MAXDATA 1000
struct Node
{
	int* data; // 存储堆的数据
	int size; // 当前数组的大小
	int Maxsize; //数组容量的大小
}

建立一个堆

MaxHeap createMaxHeap(int Max)
{
	MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
	H->data = (int*)malloc((Max+1) * sizeof(int));
	H->data[0] = MAXDATA; //把第一个节点的值设为最大的值
	H->Maxsize= Max;
	H->size = 0;
	return H;
}

判断堆是否为空

bool IsEmpty(Heap H)
{
	if(H->size == 0)
	{
		return true;
	}
	return false;
}

判断堆是否满

bool IsFull(Heap H)
{
	if(H->size == H->Maxsize)
		return true;
	return false;

向堆中插入元素

void InsertHeap(Heap H , int item)
{
	if(Isfull(H))
	{
		printf("堆已满\n");
		return;int i ;
	i = ++H->size; //更新size
	for(;H->data[i/2]<item;i/=2)  //向上比较,寻找插入位置
	{
		H->data[i] = H->data[i/2]; 
	}
	H->data[i] = item; //插入元素
}

从堆中取出一个元素

int DeleteMaxHeap(Heap H)
{
	int Parent, Child, Tmp; 
	int Maxitem;
	if (IsEmpty(H))
	{
		printf("堆为空");
		return -1;
	}
	Maxitem = H->data[1]; //取出最大元素
	Tmp = H->data[H->size--]; //取出最后一个元素
	// 把最后一个元素向下比较,寻找插入位置
	for (Parent = 1; Parent * 2 <= H->size; Parent = Child)
	{
		Child = Parent * 2;
		if ((Child != H->size)&& H->data[Child +1]>H->data[Child])
		{
			Child++;
		}
		if (Tmp >= H->data[Child])
		{
			break;
		}
		else
		{
			H->data[Parent] = H->data[Child];
		}
	}
	H->data[Parent] = Tmp; // 把最后一个元素放在合适的位置
	return Maxitem;
}

堆的建造

void PercDown(Heap H, int p)
{
	if (IsEmpty(H))
	{
		printf("堆为空");
		return;
	}
	int Parent, Child, Tmp;
	Tmp = H->data[p];
	for (Parent = 1; Parent * 2 <= H->size; Parent = Child)
	{
		Child = Parent * 2;
		if ((Child != H->size)&& H->data[Child +1] > H->data[Child])
		{
			Child++;
		}
		if (Tmp < H->data[Child])
		{
			H->data[Parent] = H->data[Child];
		}
		else
		{
			break;
		}
	}
	H->data[Parent] = Tmp;
}

void BuildHeap(Heap H)
{ 
/* 调整H->Data[]中的元素,使满足最大堆的有序性  */
/* 这里假设所有H->Size个元素已经存在H->Data[]中 */
	int i;
	/* 从最后一个结点的父节点开始,到根结点1 */
	for (i = H->size / 2; i > 0; i--)
		PercDown(H, i);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值