优先队列(堆)的基本结构(1):

本文介绍了优先队列的基本概念及其实现方式,利用数组表示的堆结构来维护队列中元素的优先级顺序。文章详细阐述了如何通过插入与删除操作保持堆的特性,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:优先队列是指的队列可以提高最高优先级的信息,并且它的删除与插入操作都可以保证这个结构不被破坏;

(1)基本数据结构:由一个代表堆大小的变量,堆容量的变量,还有一个可以动态分配的数组.
(2)数组的第一个元素不用,编号从1开始.,该队列可以看成一棵二叉树,父节点总是比子节点要小.。同时堆是一个被完全填满的二叉树,有可能的例外是在最后一层.
这里写图片描述
(3)可以用一个数组来存放堆,因为很容易证明(数学归纳法)如果一个节点的标号是i,那么它的左儿子是2i,右儿子是2i+1;
这里写图片描述
(4)注意第一个元素存放了一个比所有实际数据都小的值,这样在进行后面的例程有一点好处.

#include "stdafx.h"
#include "string.h"
#include "stdlib.h"
#include "malloc.h"
#define Mindata -1000;
typedef struct Heapstruct* Heap;
struct Heapstruct
{
    int heapsize;
    int Capcity;
    int *Element;
};
int IsFull(Heap H)
{
    if(H->heapsize == H->Capcity)
        return 1;
    else
        return 0;
}
int IsEmpty(Heap H)
{
    if(H->heapsize == 0)
        return 1;
    else
         return 0;
}

Heap Initialize(int Size)
{
    Heap H;
    H = (Heap)malloc(sizeof(Heapstruct));
    if(Size <=0)
    {  
        puts("the size must be positive");
        return NULL;
    }
    H->heapsize = 0;
    H->Capcity = Size;
    H->Element = (int *)malloc(sizeof(int)*(Size+1));
    H->Element[0] = Mindata;
    return H;
}

下面是插入例程:
注意到,和二叉平衡树一样,我们要保证插入操作不能破坏掉堆的大小关系结构;首先从最后一个节点往上溯搜寻。当某个节点比要插入的元素大时,那么可以将该元素放入这个节点.但是被覆盖掉的元素怎么办呢?因此在搜寻的时候我们就要进行移位,使得每一个搜寻路径上的元素都往后退一格,(从另一个角度也是最后的空节点在不停的往上走),直到空穴找到合适插入的位置.这种操作叫做

void Insert(Heap H,int x)
{
    int i;
    if(IsFull(H))
    {
        puts("the heap is full");
        exit(1);
    }
    else
    { 
        for(i = ++H->heapsize; x<H->Element[i/2];i/=2)
            H->Element[i] = H->Element[i/2];
            H->Element[i] = x;
    }
}

下面是删除的例程:
删除例程:每次删除都是删除最小的.删除根是很简单的,难点在于如何安排后面的元素。基本思路是选取根中最小的儿子,将它上移动到空出的根节点.这样又会空出一个新的空穴,检测最后的节点是否适合该空穴(小于该空穴的两个子女),这样该空穴将一路下溯,直到满足条件。
但有一些小细节需要注意.
[1]首先我们要保证不会降至最后一层,因为最后一层的节点没有儿子.
[2]其次要注意有可能有一个节点只有一个儿子,我们必须进行检测;

void DeleteMin(Heap H)
{
    if(!IsEmpty(H))
    {
        int LastElement = H->Element[H->heapsize--];
        int child,i;
        for( i = 1;i*2<=H->heapsize;i = child)
        {
            child = i*2;
            if(child !=H->heapsize&&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;
    }
    else
        puts("the heap is empty");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值