堆(Heap)

浙大数据结构
堆(Heap)
最大堆(MaxHeap)和最小堆(MinHeap)

结构性:用数组表示 完全二叉树
有序性:
任一结点的关键字是其子树所有结点的最大值(或最小值)
从根结点到任意结点路径上结点序列的有序性

#include <iostream>
#include <cstdlib>
 
using namespace std;

typedef int ElementType;

typedef struct HeapStruct{
	ElementType *Elements;//存储堆元素的数组 
	int Size;//堆的当前元素个数 
	int Capacity;//堆的最大容量 
}MaxHeap;

/* 创建最大堆 */
MaxHeap *Create(int MaxSize){
	MaxHeap *H = (MaxHeap *)malloc(sizeof(MaxHeap));
	H->Elements = (ElementType *)malloc((MaxSize+1) * sizeof(ElementType));
	H->Size = 0;
	H->Capacity = MaxSize;
	//H->Elements[0] = MaxData;  定义哨兵为大于堆中所有可能元素的值 
	return H; 
}

/* 判断堆满 */
int IsFull(MaxHeap *H){
	return (H->Size == H->Capacity);
} 

/* 插入元素 */ 
void Insert(MaxHeap *H, ElementType item){
	int i;
	if(IsFull(H)){
		cout << "最大堆已满!" << endl;
		return ; 
	}
	i = ++H->Size;
	/* 条件i>1 或 [0]哨兵 */ 
	//H->Elements[0] = item; 
	for(i; i>1 && H->Elements[i/2]<item; i=i/2){//数组顺序存储完全二叉树元素值 
		H->Elements[i] = H->Elements[i/2];//向下过滤结点 
	}
	H->Elements[i] = item;//将item插入 
} 
/* 判断堆空 */
int IsEmpty(MaxHeap *H){
	return (H->Size == 0);
} 
/* 删除元素 */
ElementType DeleteMax(MaxHeap *H){
	/* 先保留结构特性 在调整有序特性 */
	int Parent, Child;
	ElementType MaxItem, temp;
	if(IsEmpty(H)){
		cout << "最大堆已空!" << endl;
		return NULL; 
	}
	MaxItem = H->Elements[1];
	temp = H->Elements[H->Size--];
	for(Parent=1; Parent*2<=H->Size; Parent=Child){//Parent=Child 移动到下一层 
		/* 假设左儿子较大 */ 
		Child = Parent * 2;//一个完全二叉树的数组存储  父亲的两倍是左儿子 +1是右儿子 
		if((Child!=H->Size) && (H->Elements[Child]<H->Elements[Child+1])){
			Child++;//Child指向左右子结点的较大者 
		}
		if(temp >= H->Elements[Child]){
			break;//比较大的儿子还要大,就返回他的父亲下标 Parent 
		}else{//否侧就用较大儿子代替父亲 
			H->Elements[Parent] = H->Elements[Child];
		}
	}
	H->Elements[Parent] = temp; 
	return MaxItem;
} 
/**最大堆的建立 
将已经存在的N个元素按最大堆的要求存放在一个一维数组中 
1)通过插入操作,将N个元素一个个相继插入到一个初始为空的堆中,
其时间复杂度为O(N logN)。
2)在线性时间复杂度下建立最大堆。
1.将N个元素按输入顺序存入,先满足完全二叉树的结构特性
2.调整各个结点位置,以满足最大堆的有序特性 
//使用DeleteMax()策略 
*/ 

/* 2 1 4 5 3 6 9 8 7 0 */ 
int main(){
	MaxHeap *H;
	int MaxSize = 10; 
	H = Create(MaxSize);
	 
	if(IsEmpty(H)) cout << "堆空!" << endl;
	
	for(int i=0; i<MaxSize; i++){
		ElementType item;
		cin >> item;
		Insert(H, item); 
		if(IsFull(H)) cout << "堆满!" << endl;
	}
	
	for(int i=0; i<MaxSize; i++){
		 cout << DeleteMax(H) << " ";
		 if(IsEmpty(H)) cout << endl << "堆空!" << endl;
	}
	
	return 0;
} 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值