优先队列的数组、二叉堆实现

一个合适的数据结构应该支持两种操作:删除最大元素和插入元素。这种数据类型叫做优先队列

实现栈或是队列与实现优先队列的最大不同在于对性能的要求。对于栈和队列,我们的实现能够在常数时间内完成所有操作;
而对于优先队列,我们刚刚讨论过的所有初级实现中,插入元素删除最大元素这两个操作之一在最坏情况下需要线性时间来完成。

这里写图片描述


API

这里写图片描述

一个优先队列的用例

问题:输入N个字符串,每个字符串都对映着一个整数,从中找出最大的M个整数。
分析:

  • 将输入排序然后从中找出M个最大的元素(不适于输入非常大的情况)
  • 将每个新的输入和已知的M个最大元素比较(除非M较小,否则这种比较的代价非常高昂)
public class TopM
{
    public static void main(String[] args)
    {
        //打印输入流中最大的M行
        int M = Integer.parseInt(args[0]);
        MinPQ<Transaction> pq = new MinPQ<Transaction>(M+1);

        while(StdIn.hasNextLine())
        {
            //为下一行输入创建一个元素并放入优先队列中
            pq.insert(new Transation(StdIn.readLine()));
            if(pq.size() > M)
                pq.delMin(); //如果优先队列中存在M+1个元素删除其中最小的元素
        } //最大的M个元素都在优先队列中

        Stack<Transaction> stack = new Stack<Transaction>();
        while(Qpq.isEmpty()) stack.push(pq.delMin());
        for(Transaction t : stack) System.out.println(t);
        //降序打印
    }
}

初级实现

数组实现(无序)

基于数组的下压栈。

  • insert()跟push()完全一样
  • delMax()可以对pop()添加选择排序的内循环,将最大元素和边界元素交换然后删除它。
数组实现(有序)
  • insert()中添加插入排序,将所有较大的元素向右移动一格以使数组保持有序。
  • delMax()和pop()一样。
链表表示法

基于链表的下压栈,其他修改同数组实现。

二叉堆实现
堆的定义

当一颗二叉树的每个节点都大于等于它的两个子节点时,它被称为堆有序

二叉堆表示法

完全二叉树只用数组而不需要指针就可以表示。将二叉树的节点按照层级顺序放入数组中。

二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级储存(不使用数组的第一个位置)。
——在一个堆中,位置k的节点的父节点的位置为【k/2】,而它的两个子节点的位置分别为2k和2k+1。

堆实现的比较和交换方法
这里写图片描述

堆有序化(上浮)
这里写图片描述

堆有序化(下沉)
这里写图片描述

基于堆的优先队列
这里写图片描述

参考《Algorithm》

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值