您的位置:首页 > 其它

二叉堆(优先队列)

2010-06-25 13:05 204 查看
/*===========*/
| 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: