【MOOC】Binary Tree -Part III Heap

博客介绍了Heap堆的概念,它与优先队列相关,有最大堆和最小堆。堆具有用数组表示的完全二叉树、结点关键字有序等特性。还阐述了最大堆的操作,如创建、判断满或空、插入和删除元素等,插入和删除时需调整堆的形态,最后提到建造最大堆。

Heap 堆

考虑堆的概念,可以先考虑<优先队列>,取出元素的顺序是按照元素的优先级大小,而不是进入队列的先后顺序,即每次取出最大值或者最小值,则对应了最大堆MaxHeap和最小堆MinHeap的概念。

堆的两个特性:

>用数组表示的完全二叉树

>任意结点的关键字是其子树所有结点的最大值(或者最小值),满足从根结点到任意路径上结点序列的有序性


最大堆的操作:

>MaxHeap Create(int MaxSize):创建一个空的堆

struct HeapStruct
{
	int *vals;		/*存储堆元素的数组*/
	int size;		/*堆当前元素个数*/
	int capacity;	/*堆的最大容量*/
};

MaxHeap Create(int MaxSize)
{
	#define MaxData  1000
	MaxHeap H = (MaxHeap)malloc(sizeof(struct HeapStruct));
	H->vals = (int *)malloc((MaxSize+1)*(sizeof(int)));/*堆元素从数组下标1开始,因此+1多分配一个空间*/
	H->size = 0;
	H->capacity = MaxSize;
	H->vals[0] = MaxData;/*作为“哨兵”使用*/
};

>Boolean IsFull(MaxHeap H):判断最大堆H是否已满

bool IsFull(MaxHeap H)
{
	return (H->size == H->capacity);
}

>Boolean Insert(MaxHeap H,ElementType item):将元素item插入最大堆H

插入堆,需要调整堆的形态!

bool Insert(MaxHeap H, int x)
{
	/*H->val[0]已经定义为哨兵*/
	int i;
	
	if(IsFull(H)){/*判断堆可否为满*/
		printf("Heap is full\n");
		return false;
	}
	i = ++H->size;/*size++,同时找到调整位置的起始点i*/
	for (; H->vals[i/2]<x; i = i/2){/*比较起始点和父节点大小,一直比较到根结点*/ 
		H->vals[i] = H->vals[i/2];/*如果没有定义哨兵,则判断条件增加i>1*/
	}
	H->vals[i] = x;
	return true; 
}

>Boolean IsEmpty(MaxHeap H):判断最大堆H是否为空

bool IsEmpty(MaxHeap H)
{
	return (H->size == 0);
}

>ElementType DeleteMax(MaxHeap H):返回H中最大元素

删除堆的根结点,则同样需要调整堆的形态!

/*从最大堆中取出键值最大的结点,删除之*/ 
int DeleteMax(MaxHeap H)
{
	int MaxItem;
	int x;
	int parent, child;
	 
	if(IsEmpty(H)){
		printf("Heap is empty\n");
		return -1;
	}
	MaxItem = H->vals[1];/*最大值为根结点,即val[1]*/ 
	x = H->vals[H->size--];
	for (parent = 1; parent*2<=H->size; parent = child){
		child = 2*parent;
		if ((child != H->size) && (H->vals[child]<H->vals[child+1])){
			child++;
		}
		if (x>=H->vals[child])
			break;
		else
			H->vals[parent] = H->vals[child];	 
	}
	H->vals[parent] = x;
	return MaxItem;
}

建造最大堆

void PercDown(MaxHeap H, int i)
{
	/*将H中以i为根的子堆调整为最大堆*/
	int parent, child;
	int x;
	
	x = H->vals[i];
	for (parent = i; parent*2<=H->size;parent = child){
		child = 2*parent;
		if ((child != H->size) && (H->vals[child]<H->vals[child+1])){
			child++;
		}
		if (x>=H->vals[child]) break;
		else
			H->vals[parent] = H->vals[child]; 
	}
	H->vals[parent] = x;
	return;
	
}

void BuildHeap(MaxHeap H)
{
	int i;
	
	for(i = H->size/2; i>0; i--){
		PercDown(H, i);
	}
	return;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值