/*===========*\
| binheap.h |
\*===========*/
#ifndef _BINHEAP_H_
#define _BINHEAP_H_
#define ElementType int
#define MinPQSize 2
#define MinData -10000
typedef struct HeapStruct {
int Capacity;
int Size;
ElementType * Elements;
} * PriorityQueue;
//function list
PriorityQueue Initialize(int MaxElements);
void Destroy(PriorityQueue h);
void MakeEmpty(PriorityQueue h);
void Insert(ElementType x,PriorityQueue h);
ElementType DeleteMin(PriorityQueue h);
ElementType FindMin(PriorityQueue h);
int IsEmpty(PriorityQueue h);
int IsFull(PriorityQueue h);
#endif
/*=============*\
| binheap.c |
\*=============*/
#include "binheap.h"
#include <stdio.h>
#include <stdlib.h>
//初始化优先队列
PriorityQueue Initialize(int MaxElements)
{
PriorityQueue h;
if (MaxElements < MinPQSize)
printf("out of space!!\n");
h = (PriorityQueue)malloc(sizeof(struct HeapStruct));
if (h == NULL)
printf("out of space!!\n");
h->Elements = (ElementType *)malloc((MaxElements+1)*sizeof(ElementType));
if (h->Elements == NULL)
printf("out of space!!\n");
h->Capacity = MaxElements;
h->Size = 0;
h->Elements[0] = MinData;
return h;
}
//判断队列是否已满
int IsFull(PriorityQueue h)
{
return h->Size == h->Capacity-1;
}
//判断队列是否为空
int IsEmpty(PriorityQueue h)
{
return h->Size == 0;
}
//插入节点
void Insert(ElementType x,PriorityQueue h)
{
int i ;
if (IsFull(h))
{
printf("Priority queue is full\n");
return;
}
for(i=++h->Size;h->Elements[i/2]>x;i/=2)
h->Elements[i] = h->Elements[i/2];
h->Elements[i]=x;
}
//从节点p下滤
void percolateDown(int p,PriorityQueue h)
{
int i = p;
if (p>h->Size)
{
printf("Out of the size !! : p=%d,size=%d\n",p,h->Size);
return;
}
ElementType element = h->Elements[p];
while (i*2<=h->Size)
{
int minChild = (2*i != h->Size) && (h->Elements[2*i]>h->Elements[2*i+1]) ? 2*i+1 : 2*i;
if(element>h->Elements[minChild])
{
h->Elements[i] = h->Elements[minChild];
i=minChild;
}
else
break;
}
h->Elements[i] = element;
}
//从节点P上滤
void percolateUp(int p,PriorityQueue h)
{
int i;
if (p>h->Size)
{
printf("Out of the size !!\n");
return;
}
ElementType element = h->Elements[p];
for(i=p;h->Elements[i/2]>element;i=i/2)
h->Elements[i] = h->Elements[i/2];
h->Elements[i]=element;
}
//删除最小元
ElementType DeleteMin(PriorityQueue h)
{
int i,Child;
ElementType 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)
{
/* find smaller child */
Child = i*2;
if (Child != h->Size && h->Elements[Child+1]
< h->Elements[Child])
Child++;
/* percolate one level */
if (LastElement > h->Elements[Child])
h->Elements[i] = h->Elements[Child];
else
break;
}
h->Elements[i]=LastElement;
return MinElement;
}
//降低关键字的值
void DecreaseKey(int P,ElementType value,PriorityQueue h)
{
h->Elements[P] -= value;
percolateUp(P,h);
}
//增加关键字的值
void IncreaseKey(int P,ElementType value,PriorityQueue h)
{
h->Elements[P] += value;
percolateDown(P,h);
}
//删除节点
void Delete(int P,PriorityQueue h)
{
DecreaseKey(P,-10000,h);
DeleteMin(h);
}
//构建堆
void BuildHeap(ElementType * et,int n,PriorityQueue h)
{
int i;
h->Size = n;
if (n>h->Capacity)
{
printf("Out of the capacity!\n");
return;
}
for(i=0;i<n;i++)
{
h->Elements[i+1] = et[i];
}
for(i=n/2;i>0;i--)
percolateDown(i,h);
}
//打印二叉堆(优先队列)
void printBinHeap(PriorityQueue h)
{
int i;
for(i=1;i<=h->Size;i++)
printf("%d ",h->Elements[i]);
putchar('\n');
}
//////////////////////////////////////////////////////////////////////////
int main()
{
ElementType a[]={19,18,7,3,4,9,11,22,12};
PriorityQueue h = Initialize(20);
BuildHeap(a,sizeof(a)/sizeof(int),h);
printBinHeap(h);
DecreaseKey(8,20,h);
printBinHeap(h);
IncreaseKey(1,20,h);
printBinHeap(h);
Delete(1,h);
printBinHeap(h);
Insert(3,h);
printBinHeap(h);
system("pause");
return 0;
}