最小堆,能够维护最的的元素的最上面。同样还有最大堆等
#include <stdio.h>
#include<stdlib.h>typedef int ElementType;
ElementType MinDate = -10000 ;
struct HeapStruct;
typedef struct HeapStruct *PriorityQueue;
PriorityQueue Initialize(int Maxelement); //创建并初始化
void Destory(PriorityQueue H); //销毁最小堆
void MakeEmpty(PriorityQueue H); //清空堆
void Insert(ElementType X,PriorityQueue H); //插入X
ElementType DeleteMin(PriorityQueue H); //删除堆中最小值
ElementType FindMin(PriorityQueue H); //查找最小值,返回最小值
int IsEmpty(PriorityQueue H); //判空
int IsFull(PriorityQueue H); //判满
int main(void) //主函数,最小堆,利用顺序储存结构
{
PriorityQueue H;
H = Initialize(40);
Insert(45,H);
Insert(11,H);
Insert(30,H);
Insert(88,H);
printf("%d\n",FindMin(H));
// printf("Hello World!\n");
return 0;
}
struct HeapStruct
{
int Capacity;\
int Size;
ElementType *Elements;
};
PriorityQueue Initialize(int Maxelement) //创建并初始化一个最小堆
{
PriorityQueue H;
H = (PriorityQueue)malloc(sizeof(struct HeapStruct)); //为总的结构体发配空间
if( NULL == H)
{
printf("Out of Space\n");
}
//为结构体中数组发配空间,其中储存每个元素
H->Elements = (ElementType*)malloc((Maxelement + 1) * sizeof(ElementType));
if(NULL == H->Elements )
{
printf("Out of Space\n");
}
H->Capacity = Maxelement; //储存数组最大值
H->Size = 0; //初始化size
H->Elements[0] = MinDate; //初始化最小值
return H;
}
void Insert(ElementType X, PriorityQueue H)
{
int i;
if(IsFull(H)) //判满
{
printf("Priority Is Full\n");
} //每次插入一次,size++一次。建立一个空穴
for(i = ++H->Size; H->Elements[i / 2] > X;i /= 2) //如果X小于父亲的值,空穴上移一层
{
H->Elements[i] = H->Elements[i/2];
}
H->Elements[i] = X; //将X填入空穴
}
void Destory(PriorityQueue H)
{
free(H->Elements);
free(H);
}
void MakeEmpty(PriorityQueue H)
{
H->Size = 0;
}
/*
删除最小元比较容易,因为堆中第一个元素就是最小元。难的是删除最小元后,怎么维护这个最小堆。
一种思路是,将儿子节点中较小的那个提为父亲,一直这样下去,直到最后一层。也就是将空穴一直
沿着最小元传递下去
*/
ElementType DeleteMin(PriorityQueue H) //删除堆中最小值
{
int i,Child;
ElementType MinElement,LastElement;
if(IsEmpty(H))
{
printf("Priority Is Empty\n");
return H->Elements[0];
}
MinElement = H->Elements[1]; //堆中最小的元素
LastElement = H->Elements[H->Size--]; //堆中最后一个元素,因为从数组从1开始,所以要size--
//并且size--,也标志着数组中元素减一
for(i = 1; i * 2 <= H->Size; i = Child )
{
Child = 2 * i;
if(Child != H->Size && H->Elements[Child + 1] < H->Elements[Child]) //找到左右孩子中较小的
Child++;
if(LastElement > H->Elements[Child])
H->Elements[i] = H->Elements[Child];
else
break;
}
H->Elements[i] = LastElement;
return MinElement;
}
ElementType FindMin(PriorityQueue H) //堆中最小元为数组下标为1的元素
{
if(IsEmpty(H))
{
printf("Priority Is Empty\n");
return H->Elements[0];
}
return H->Elements[1];
}
int IsEmpty(PriorityQueue H) //如果数组大小为0的话,数组为空
{
return H->Size == 0;
}
int IsFull(PriorityQueue H) //如果数组的大小为最大值的话,数组满了
{
return H->Size == H->Capacity;
}