优先队列:优先队列是允许至少下列两种操作的数据结构:Insert(插入)和 DeleteMin(删除最小者)
我们使用二叉堆来实现优先队列
堆的性质:堆是一颗完全二叉树(只有最下面的两层结点度能够小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树),完全二叉树可以用数组表示,对于数组中任一为位置i上的元素,其左儿子在位置2i 上,右儿子在(2i + 1)上
堆序性质:在一个堆中,对于每个节点X, X的父亲中的关键字小于(或等于)X中的关键字,根节点除外(它没有父亲节点)
#include <stdio.h>
#include <stdlib.h>
#define Mindata (-32767)
typedef struct HeapStruct{
int Size;
int Capacity;
int *Elements;
}*PriorityQueue, HeapStruct;
PriorityQueue Initialize(int MaxElements){//初始化列队,利用及结构体构建一个最多元素为MaxElements的二叉堆
PriorityQueue H;
H = (PriorityQueue )malloc(sizeof(HeapStruct));
H -> Elements = (int *)malloc((MaxElements + 1) * sizeof(int));
H -> Size = 0;
H -> Capacity = MaxElements;
H -> Elements[0] = Mindata;
return H;
}
void Insert(PriorityQueue H, int X){//向二叉堆里面插入元素
int i;
for(i = ++H -> Size; H -> Elements[i / 2] > X; i /= 2){
H -> Elements[i] = H -> Elements[i / 2];
}
H -> Elements[i] = X;
}
int DeleteMin(PriorityQueue H){//删除最小节点,即根节点
int i, child, LastElement, MinElement;
MinElement = H -> Elements[1];
LastElement = H -> Elements[H -> Size--];
for( i = 1; 2 * i <= H -> Size; i = child){
child = 2 * i;
if(child != H -> Size && H -> Elements[child] > H -> Elements[child + 1]){
child++;
}
if(LastElement > H -> Elements[child]){
H -> Elements[i] = H -> Elements[child];
}
else
break;
}
H -> Elements[i] = LastElement;
return MinElement;
}
int main(){
int Array[] = { 32, 21, 16, 24, 31, 19, 68, 65, 26, 13 };
PriorityQueue H;
H = Initialize(50);
int i;
for( i = 0; i < 10; i++){
Insert(H, Array[i]);
}
for(i = 0; i < 10; i++){
printf("%d ", DeleteMin(H));
}
return 0;
}