数据结构笔记(5)优先队列(堆)

优先队列(priority queue)

优先队列允许至少下列两种操作的数据结构:

  • Insert
  • DeleteMin : 找出、返回、删除优先队列中最小的元素
实现
  • 简单链表
  • 二叉查找树
  • 二叉堆(binary heap)
二叉堆
  1. 结构性
    堆是一颗被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右的填入,这样的树被称为完全二叉树
    一颗高为h的完全二叉树有2^h到2^(h+1)-1个节点。
    根据完全二叉树的特性,我们可以用数组来表示完全二叉树:

    • 对于数组中任一位置i上的元素,其左儿子在位置2i上,右儿子在左儿子后的单元(2i+1)中,它的父亲则在位置(i/2)上。
  2. 堆序性
    在一个堆中,对于每一个节点X,X的父亲中的关键字小于(或等于)X中的关键字,根节点除外。(最小堆情况)

基本的堆操作
Insert
  1. 插入新节点时,在下一个空闲位置创建一个空穴,否则该堆将不满足其结构性——完全二叉树的性质。
  2. 如果被插入的节点可以放在该空穴而且不破坏该堆的堆序性,则插入完成。如果被插入的节点破坏了堆序性质,我们采取上滤(percolate up)的策略来使其找到正确的位置。
  3. 上滤过程图示:
    (图)
  4. 代码实现
void insert(int X,PriorityQueue H)
{
    int i;
    if(IsFull(H))
    {
        printf("the 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;//将元素插入到正确位置
}
deleteMin
  1. 找到最小元(根节点),删除,此时堆中产生一个空穴。
  2. 将空穴的两个儿子中的较小者移入空穴,以保持堆序性。
  3. 重复步骤2,直到堆中最后一个元素x被放入空穴。
  4. 与上滤对应,这个过程称为下滤(percolate down)。
  5. 下滤图示:
    (图)
  6. 代码实现:
int DeleteMin(PriorityQueue H)
{
    int i,Child;
    int MinElement,lastElement;
    if(IsEmpty(H))
    {
        printf("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)
    {
        /** Find smaller Child */
        Child=i*2;//从第一层开始比较最小节点,同时保证Child必为左子树索引
        if(Child!=H->Size&&H->elements[Child+1]<H->elements[Child])
            Child++;
        //如果右子树比左子树小,返回右子树,否则返回左子树
        //如果Child已经为最后一个节点的索引,直接返回

        /** Percolate one level */
        if(lastElement > H->elements[Child])
            H->elements[i]=H->elements[Child];//空节点下滤
        else break;//如果子树根节点比最后一个节点大,直接跳出循环

    }
    H->elements[i]=lastElement;//将空节点与最后一个节点交换
    return MinElement;//返回堆中最小值
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值