二叉堆(優先對列)

/*===========*\
 | 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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章