优先队列之二叉堆

  在操作系统中,调度程序必须决定在什么时候运行哪个进程。一般来说,短的作业是需要尽可能快地完成,也就是说,短的作业应该拥有优先权。这种特殊的应用将由一种特殊的队列来完成,这种数据结构叫做优先队列,属于计算机科学中最讲究的一种。

 

一、最基本的两种操作

  优先队列具备的最基本的两种操作,是插入和删除最小者。插入操作相当于入列,而删除操作相当于出队。只是这里有一些地方是不同的,不像之前出队和入队操作那么简单。

 

二、二叉堆

  一般来说,管二叉堆叫堆,它的应用非常普遍。而堆就是一棵完全二叉树。这种数据结构有一个特点,就是存储它的元素可以用数组来存储,不必动用指针。对于数组中任意一个位置i上面的元素,它的左儿子在位置2i上,右儿子在(2i + 1)上;父节点则在位置(i/2)上。

  堆序的另外一个特性,就是每一个节点X,X的父亲中关键字小于或者等于X,根节点例外,因为根节点并没有父节点。

  下面是《DSAAC》中对这种数据结构的实现,插入和删除的操作可谓经典:

代码
 
   
#ifndef _BinHeap_H
#define _BinHeap_H

typedef
int ElementType;

struct HeapStruct;
typedef
struct HeapStruct * PriorityQueue;

PriorityQueue Initizlize(
int MaxElement);
void Destroy(PriorityQueue h);
void Insert(ElementType x, PriorityQueue h);
ElementType DeleteMin(PriorityQueue h);
int IsEmpty(PriorityQueue h);
int IsFull(PriorityQueue h);

#endif

 

代码
 
   
#include < stdio.h >
#include
< stdlib.h >
#include
< string .h >
#include
" binheap.h "

#define MINDATA -1
#define MIN_ELEMENT_SIZE 10

struct HeapStruct
{
int capacity;
int size;
ElementType
* element;
};

int IsEmpty(PriorityQueue h)
{
return h -> size == 0 ;
}

int IsFull(PriorityQueue h)
{
return h -> size == h -> capacity;
}

PriorityQueue Initizlize(
int MaxElement)
{
PriorityQueue h;

if (MaxElement < MIN_ELEMENT_SIZE)
{
fprintf(stdout,
" the size is too small.\n " );
return NULL;
}

h
= malloc( sizeof ( struct HeapStruct));
if (h == NULL)
{
fprintf(stdout,
" failed to create a heap struct.\n " );
return NULL;
}
h
-> element = malloc( sizeof (ElementType) * (MaxElement + 1 ));
if (h -> element == NULL)
{
fprintf(stdout,
" failed to create a heap struct.\n " );
return NULL;
}
h
-> capacity = MaxElement;
h
-> size = 0 ;
h
-> element[ 0 ] = MINDATA;

return h;
}

void Insert(ElementType x, PriorityQueue h)
{
int i;
if (IsFull(h))
{
fprintf(stdout,
" heap is full.\n " );
return ;
}
for (i = ++ h -> size; h -> element[i] > x; i /= 2 )
{
h
-> element[i] = h -> element[i / 2 ];
}
h
-> element[i] = x;
}

ElementType DeleteMin(PriorityQueue h)
{
int i, child;
ElementType MinElement, LastElement;

if (IsEmpty(h))
{
fprintf(stdout,
" the queue is empty.\n " );
return h -> element[ 0 ];
}

MinElement
= h -> element[ 1 ];
LastElement
= h -> element[h -> size -- ];

for (i = 1 ; i * 2 <= h -> size; i = child)
{
child
= i * 2 ;
if (child != h -> size && (h -> element[child + 1 ] < h -> element[child]) )
{
child
++ ;
}
if (LastElement > h -> element[child])
{
h
-> element[i] = h -> element[child];
}
else
{
break ;
}
}
h
-> element[i] = LastElement;
return MinElement;
}

#define SAFE_FREE(h) {if(h) {free(h); h = NULL;} }
void Destroy(PriorityQueue h)
{
if (h == NULL)
{
fprintf(stdout,
" [Destroy]the pointer is NULL.\n " );
return ;
}
SAFE_FREE(h
-> element);
SAFE_FREE(h);
}

 

转载于:https://www.cnblogs.com/python_newbie/archive/2010/10/30/1865126.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值