优先队列之二叉堆

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

 

一、最基本的两种操作

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

 

二、二叉堆

  一般来说,管二叉堆叫堆,它的应用非常普遍。而堆就是一棵完全二叉树。这种数据结构有一个特点,就是存储它的元素可以用数组来存储,不必动用指针。对于数组中任意一个位置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);
}

 

posted @ 2010-10-30 16:18  Linjian  阅读(1043)  评论(1编辑  收藏  举报