优先队列的实现(建堆)

参考书目《数据结构与算法分析(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;
}

测试结果


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值