数据结构与算法分析---优先队列(二叉堆)的实现(C语言)

优先队列,是一种特殊的队列,队列取出元素是按照先进先出的顺序,而优先队列是为每一个元素都赋予一个优先级,按照优先级的大小取出,这里的优先级通常是元素的大小,所以有最大堆和最小堆,使用二叉堆这种数据结构来实现优先队列,二叉堆有两种性质,第一种是结构性质,是一棵完全二叉树,这样我们可以利用数组来存储元素,并且能快速的找到父亲节点(i/2)和左(2*i)右(2*i+1)儿子,另一种是堆序性,父节点的值小于等于子节点的值,所以根节点为最小值,叫最小堆,反之,最大堆。有两种重要操作,插入元素和删除并返回最小值,下面给出这两种操作的C语言实现方式

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

struct HeapStruct;
typedef struct HeapStruct* PriorityQueue;
typedef int ElementType;

struct HeapStruct
{
    int Capacity;
    int Size;
    ElementType* Elements;
};

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);

PriorityQueue Initialize(int MaxElements)
{
    PriorityQueue H;
    H = (PriorityQueue) malloc(sizeof(struct HeapStruct));
    H -> Capacity = MaxElements;
    H -> Size = 0;
    H -> Elements = (ElementType*) malloc( sizeof(ElementType) * (MaxElements + 1) );
    H -> Elements[0] = INT_MIN;
    return H;
}
void Destroy(PriorityQueue H)
{
    free(H -> Elements);
    free(H);
}
void MakeEmpty(PriorityQueue H)
{
    H -> Size = 0;
}
void Insert(ElementType X,PriorityQueue H)
{
    if(isFull(H)) {
        printf("FULL!!!!!!!!!\n");
    }
    else {
        int i;
        for(i = ++H -> Size; X < H -> Elements[i / 2]; i /= 2) {
            H -> Elements[i] = H -> Elements[i / 2];
        }
        H -> Elements[i] = X;
    }
}
ElementType DeleteMin(PriorityQueue H)
{
    if(isEmpty(H)) {
        printf("EMPTY!!!!!!!!!!!\n");
    }
    else {
        ElementType Min,Last;
        int Child,Parent;
        Min = H -> Elements[1];
        Last = H -> Elements[H -> Size--];
        for(Parent = 1; Parent * 2 <= H -> Size; Parent = Child) {
            Child = Parent * 2;
            if(Child != H -> Size && H -> Elements[Child + 1] < H -> Elements[Child] ) {
                Child++;
            }
            if(Last > H -> Elements[Child]) {
                H -> Elements[Parent] = H -> Elements[Child];
            }
            else break;
        }
        H -> Elements[Parent] = Last;
        return Min;
    }
}
ElementType FindMin(PriorityQueue H)
{
    if(isEmpty(H)) {
        printf("EMPTY!!!!!!!!!!!\n");
    }
    else {
        return H -> Elements[1];
    }
}
int isFull(PriorityQueue H)
{
    return H -> Size == H -> Capacity;
}
int isEmpty(PriorityQueue H)
{
    return H -> Size == 0;
}
int main(void)
{
    PriorityQueue H = Initialize(100);
    int a[] = {80, 40, 30, 60, 90, 70, 10, 50, 20};
    int i;
    for(i = 0; i < sizeof(a) / sizeof(int); i++) {
        Insert(a[i],H);
    }
    for(i = 0; i < sizeof(a) / sizeof(int); i++) {
        printf("%d\n",DeleteMin(H));
    }
    return 0;
}

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值