堆的操作(最大堆)

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;

struct HNode{
	int *data;/*存放元素的数组*/
	int size;/*堆当前元素的个数*/
	int capacity;/*堆的最大容量*/
};

typedef struct HNode * Heap;

Heap create(int Maxsize)
{
	Heap H = (Heap)malloc(sizeof(struct HNode));
	H->data = (int *)malloc((Maxsize + 1) * sizeof(int));
	H->size = 0;
	H->capacity = Maxsize;
	H->data[0] = 1000;/*将数组下标为0的位置设置为 大于堆中任意一个数的 一个数*/
	
	return H;
} 

bool isempty(Heap H)
{
	return (H->size == 0);
	
}

bool isfull(Heap H)
{
	return (H->size == H->capacity);
}

bool Insert(Heap H,int x)
{
	if(isfull(H))
	{
		return false;
	}
	int i;
	i = ++H->size;/*i为插入后堆中最后一个数的位置(下标)*/
	for(;H->data[i/2] < x; i /= 2)/*i/2的位置是i位置的根结点的位置*/ 
	{
		H->data[i] = H->data[i/2];/*把根结点的数赋给它的子树(上滤)*/ 
	}
	H->data[i] = x;/*插入的数如果比i位置的根结点位置上的数大,数就放在i位置上*/ 
	return true;
}

int del(Heap H)
{
	if(isempty(H))
	{
		return 0;
	}
	
	int MAX,X,parent,child;
	MAX = H->data[1];
	 /* 用最大堆中最后一个元素从根结点开始向上过滤下层结点 */
	X = H->data[H->size--];/*堆中的元素数要-1*/
	for(parent = 1; parent * 2 <= H->size; parent = child)
	{
		child = parent * 2;
		if((child != H->size) && H->data[child] < H->data[child+1])
		{
			child++;/*选择左右子树最大的那个数*/
		}
		if(X >= H->data[child])break;/*parent(根结点的位置)上的数比它的子树位置(child)上的数大,说明找到了合适的位置*/
		else
		H->data[parent] = H->data[child];/*将大的那个数填充到根结点*/
		
	}
	H->data[parent] = X;
	return MAX;
}

/*建造最大堆*/

void tiaozhen(Heap H,int i)/*传入要调整的 根结点的位置(i)*/
{
	/* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
	
	int parent,child;
	int X;
	X = H->data[i];/* 取出根结点存放的值 */
	for(parent = i; parent * 2 < H->size; parent = child)
	{
		child = parent * 2;
		if((child != H->size) && H->data[child] < H->data[child + 1])
		{
			child++;
		}
		
		if(X >= H->data[child])break;
		else
		H->data[parent] = H->data[child];
	}
	H->data[parent] = X;
}

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

int main(void)
{
	Heap H = create(8);
	int x;
	for(int i = 1; i < 9; i++)
	{
		scanf("%d",&x);
		if(Insert(H,x) == false)
		{
			break;
		}
	}
	for(int i = 1 ; i < 9; i++)
	{
		printf("%d ",H->data[i]);
	}
	printf("\n\n");
	
	for(int i = 1; i < 9; i++)
	{
		printf("%d \n",del(H));
	}
	printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
	/*建造最大堆测试*/
	Heap H1 = create(8);
	H1->size = 8;
	for(int i = 1; i < 9; i++)
	{
		scanf("%d",&H1->data[i]);
	}
	for(int i = 1 ; i < 9; i++)
	{
		printf("%d ",H1->data[i]);
	}
	printf("\n\n");
	build(H1);
	 for(int i = 1; i < 9; i++)
	{
		printf("%d \n",del(H1));
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值