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;
}