参考书目《数据结构与算法分析(C语言描述)》
二叉堆是一颗完全二叉树,有最小堆和最大堆。优先队列同样具有堆序性,而它是用连续内存实现的(数组和动态申请内存),注意首元素的起始位置不同,会导致建堆存在一些差别。同时它也和队列的入队,出队例程相似,但是它对于出队的元素设定一些要求。在进程先后执行当中有用到。
//接口函数 结构定义
#ifndef _PRIOQUE_H
#define _PRIOQUE_H
struct HeapStruct
{
int Capacity;
int Size;
char *Elements;
};
typedef struct HeapStruct *PriorityQueue;
PriorityQueue InitPQ(int MaxElements);
void Destroy(PriorityQueue H);
void MakeEmpty(PriorityQueue H);
void Insert(char ch,PriorityQueue H);
char DeleteMin(PriorityQueue H);
char FindMin(PriorityQueue H);
int IsEmpty(PriorityQueue H);
int IsFull(PriorityQueue H);
void Print(PriorityQueue H);
#endif
//接口函数定义
#include <stdio.h>
#include <stdlib.h>
#include "prioque.h"
#define MinPQSize 2
#define MinData '\0'
PriorityQueue InitPQ(int MaxElements)
{
PriorityQueue H;
if(MaxElements<MinPQSize)
{
printf("Priority queue is too small!!");
return NULL;
}
H=(PriorityQueue)malloc(sizeof(struct HeapStruct));
if(H==NULL)
printf("Out of space!");
H->Elements=(char *)malloc((MaxElements+1)*sizeof(char));
if(H->Elements==NULL)
printf("Still no space!");
H->Capacity=MaxElements;
H->Size=0;
H->Elements[0]=MinData;
return H;
}
void Insert(char ch,PriorityQueue H)
{
int i;
if(IsFull(H))
{
printf("Priority queue is full!");
return;
}
for(i=++H->Size;H->Elements[i/2]>ch;i/=2) //将元素插入到合适位置
H->Elements[i]=H->Elements[i/2];
H->Elements[i]=ch;
}
char DeleteMin(PriorityQueue H)
{
int i,Child;
char MinElement,LastElement;
if(IsEmpty(H))
{
printf("Priority queue is empty!");
return H->Elements[0];
}
MinElement=H->Elements[1];
LastElement=H->Elements[H->Size--];
for(i=1;i*2<=H->Size;i=Child)//将新元素下滤再次得到堆
{
Child=i*2;
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 IsEmpty(PriorityQueue H)
{
if(H->Size==0)
return 1;
else
return 0;
}
int IsFull(PriorityQueue H)
{
if(H->Size==H->Capacity)
return 1;
else
return 0;
}
void Destroy(PriorityQueue H)
{
free(H->Elements);
free(H);
}
void Print(PriorityQueue H)
{
int i;
for(i=1;i<=H->Size;i++)
{
printf("%3c",H->Elements[i]);
if(i%5==0)
printf("\n");
}
}
//main函数入口
#include <stdio.h>
#include "prioque.h"
int main(int argc, char **argv)
{
int i;
char letter;
PriorityQueue PQ;
PQ=InitPQ(18);
char buf[18]={'A','B','C','K','L','S','G','X','Z','G','H','E','F','J','D','N','P','O'};
for(i=0;i<18;i++) //通过多次插入来建立堆
{
Insert(buf[i],PQ);
}
Print(PQ);
letter=DeleteMin(PQ);
printf("\nDelete letter is %c!\n",letter);
Print(PQ);
printf("\nNext is %c!\n",DeleteMin(PQ));
Print(PQ);
Destroy(PQ);
return 0;
}
测试结果