堆的两个特性
- 结构性:用数组表示的完全二叉树;
- 有序性:任一结点的关键字是其子树所有结点的最大值(最小值)
- “最大堆(MaxHeap)”,也称“大顶堆”:最大值
- “最小堆(MinHeap)”,也称“小顶堆”:最小值
堆的抽象数据类型描述
- 类型名称:最大堆(MaxHeap)
- 数据对象集:完全二叉树,每个结点的元素值不小于其子节点的元素值
- 操作集:最大堆H
MaxHeap,元素item
ElementType,主要操作有
- MaxHeap Creat(int MaxSize):创建一个空的最大堆。
- Boolean IsFull(MaxHeap H):判断最大堆H是否已满。
- Insert(MaxHeap H,ElementType item):将元素item插入最大堆
- Boolean IsEmpty(MaxHeap H):判断最大堆H是否为空。
- ElementType DeleteMax(MaxHeap):返回H中最大元素(高优先级)
最大堆的操作
- 最大堆的创建
typedef struct HeapStruct *MaxHeap;
struct HeapStruct{
ElementType *Elements; //存储堆元素的数组
int Size; //堆的当前元素个数
int Capacity; //堆的最大容量
}
MaxHeap Creat(int MaxSize){
MaxHeap H=malloc(sizeof(struct HeapStruct));
H->Elements=malloc((MaxSize+1)*sizeof(ElementType));
H->Size=0;
H->Capacity=MaxSize;
H->Elements[0]=MaxData; //定义哨兵为大于堆中所有可能元素的值,便于以
//后操作
return H;
}
最大堆的插入
void Insert(MaxHeap H,ElementType item){
int i;
if(IsFull(H)){
printf("最大堆已满");
return;
}
i=++H->Size //i指向插入后堆中最后一个元素的位置
for(;H->Elements[i/2]<item;i/=2) //若item大于其父节点,则互换位置
H->Elements[i]=H->Elements[i/2];
H->Elements[i]=item;
}
//首先想到将item插入到最后的位置,但若不满足最大堆的条件,则考虑将item与相关结点互换
//位置
- 最大堆的删除(删除最大值元素)(将某结点删除,将数组的最后一个元素替换删除的位置,再根据大小进行调换)
ElementType DeleteMax(MaxHeap H){
int Parent,Child;
ElementType MaxItem,temp;
if(IsEmpty(H)){
printf("最大堆已为空");
return;
}
MaxItem=H->Elements[1]; //取出根结点最大值
temp=H->Elements[H->Size--]; //将数组的最后一个元素替换根结点并将Size自动减一
for(Parent=1;Parent*2<=H->Size;Parent=Child){ //替换后进行比较调整
Child=Parent*2;
if((Child!=H->Size)&&(H->Elements[Child]<H->Elements[Child+1]))
Child++;
if(temp>=H->Elements[Child])
break;
else
H->Elements[Parent]=H->Elements[Child];
}
H->Elements[Parent]=temp; //经过上面的循环会有三种情况,将Parent指向的值替换
}
- 最大堆的建立(将已经存在的N个元素按最大堆的要求存放在一个一维数组中)
- 方法1、通过插入操作,将N个元素一个个相继插入到一个初始为空的堆中去
- 方法2、将N个元素按插入顺序存入,先满足完全二叉树的结构特性,然后调整各结点的位置,以满足最大堆的有序性。