优先队列:特殊的队列,取出元素的顺序是依据元素的优先权大小,而不是元素进入队列的先后顺序。
堆的特性符合优先队列的要求:
(1)结构性:用数组表示完全二叉树;
(2)有序性:任一节点的关键字是其子树所有节点的最大值或者最小值。
1最大堆的插入
typedef struct HNode *Heap;
struct HNode {
ElementType *Data;//存储元素的数组
int Size;//堆中当前元素个数
int Capacity;//堆的最大容量
};
typedef Heap MaxHeap;
typedef Heap MinHeap;
#define MAXDATA 1000;
MaxHeap CreateHeap(int MaxSize) {
//创建容量为MaxSize的最大堆
MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
H->Data = (ElementType*)malloc((MaxSize + 1)*sizeof(ElementType));
H->Size = 0;
H->Capacity = MaxSize;
H->Data[0] = MAXDATA;
return H;
}
bool IsFull(MaxHeap H) {
return (H->Size == H->Capacity);
}
bool IsEmpty(MaxHeap H) {
return (H->Size == 0);
}
void Insert(MaxHeap H, ElementType item) {
//将元素item插入最大堆H,其中H->Element
int i;
if(IsFull(H)) {
printf("堆已满");
return false;
}
i = ++H->Size;
for(; H->Data[i/2] < X; i/=2) {
H->Data[i] = H->Data[i/2];//上滤X
}
H->Data[i] = X;//插入X
return true;
}
2最大堆的删除
ElementType DeleteMax(MaxHeap H) {
//从最大堆H中取出最大元素,并删除一个节点,调整堆
int Parent, child;
ElementType MaxItem, X;
if(IsEmpty(H)) {
printf("堆为空");
return ERROR;
}
MaxItem = H->Data[1];//取出最大值
X = H->Data[H->Size--];//数据规模减少
for(Parent=1; Parent*2<=H->Size; Parent = Child) {
Child = Parent*2;
if((Child!=H->Size)&&(H->Data[Child]<H->Data[Child+1])) {
Child++;
}//child指向左右孩子的较大者
if(X >= H->Data[Child]) {
break;
} else {
H->Data[Parent] - H->Data[Child];
}
}
H->Data[Parent] = X;
return MaxItem;
}
3调整以任意节点为根节点的堆为最大堆
void PercDown(MaxHeap H, int p) {
int Parent, Child;
ElementType X;
X = H->Data[p];
for(parent=p; Parent*2<=H->Size; Parent=Child) {
Child = Parent*2;
if((Child != H->Size)&&(H->Data[Child]<H->Data[Child+1])) {
Child++;
}
if(X >= H->Data[Child]) break;
else {
H->Data[Parent] = H->Data[Child];
}
}
H->Data[Parent] = X;
}
void BuildHeap(MaxHeap H) {
int i;
for(i=H->Size/2; i>0; i--) {
PercDown(H, i);
}
}