优先队列--二叉堆实现

二叉堆

  • 二叉堆简介
    二叉堆是优先队列的一种实现方式
    同二叉查找树一样,二叉堆也有结构性和堆序性
  • 结构性
    堆是一棵除底层外完全被填满的树
  • 堆序性
    使操作被快速执行的性质是堆序性。在这里,我们想实现的是快速找出最小值(最大值),因此最小值(最大值)应该在根上。
    所以我们可以得出一个堆序性:在堆中,对于每一个节点X,X的父亲的值应该小于等于(大于等于)X的值。

如果你不知道二叉树这些知识,建议先自行了解这些知识

下面先给出关键的源代码,稍后再作分析

优先队列

  • 头文件代码

BinHeap.h

#ifndef BINHEAP_H_INCLUDED
#define BINHEAP_H_INCLUDED

struct HeapStruct;
typedef struct HeapStruct *PriorityQueue;

PriorityQueue Initialize( int MaxElements );
void Destroy( PriorityQueue H );
void MakeEmpty( PriorityQueue H );
void Inser( ElementType X,PriorityQueue H );
ElementType DeleteMin( PriorityQueue H );
ElementType FindMin( PriorityQueue H );
int IsEmpty( PriorityQueue H );
int IsFull( PriorityQueue H );

#endif // BINHEAP_H_INCLUDED
  • 具体实现

BinHeap.c

#include <stdio.h>
#include <stdlib.h>
#include "BinHeap.h"

PriorityQueue Initialize( int MaxElements )
{
    PriorityQueue H;

    if( MaxElements < MinPQSize)
        Error( "Priority queue size is too small" );

    H = malloc( sizeof( struct HeapStruct ) );
    if( H == NULL )
        FatalError( "Out of space!!!" );

    /* Allocate the array plus one extra for sentinel */
    H->Elements = malloc( ( MaxElements + 1 ) * sizeof( ElementType ) );
    if( H->Elements == NULL )
        FatalError( "Out of space!!!" );

    H->Capacity = MaxELements;
    H->Size = 0;
    H->Elements[0] = MinData;
}

void Insert( ElementType X,PriorityQueue H )
{
    int i;

    if( IsFull( H ) )
    {
        Error( "Priority queue is full" );
        return;
    }

    for( i = ++H->Size; H->Elements[ i / 2 ] > X; i /= 2)
        H->Elements[ i ] = H->Elements[ i / 2 ];
    H->Elements[ i ] = X;
}

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

    if( IsEmpty( H ) )
    {
        Error("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 + 1 ] < H->Elements[ Child ] )
            Child++;

        if( LastElement > H->Elements[ Child ]  )
            H->Elements[ i ] = H->Elements[ Child ];
        else
            break;
    }
    H->Elements[ i ] = LastElement;
    return MinElement;
}
点赞