浙大数据结构
堆(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;
}