数据结构算法笔记 从入门到放弃 (二)高级数据结构之优先队列如何使用

  • 优先队列
  • 前缀树
  • 后线段树
  • 树状数组

优先队列(Priority Queue)

特点:每次取出的元素都是优先级最高的。而这个优先级可以自定义。

应用场景:从一堆杂乱无章的数据当中按照一定的顺序(或者优先级)逐步地筛选出部分乃至全部的数据。

实现:优先队列的本质是一个二叉堆结构。堆在英文里叫 Binary Heap,它是利用一个数组结构来实现的完全二叉树。优先队列的本质是一个数组,数组里的每个元素既有可能是其他元素的父节点,也有可能是其他元素的子节点,而且,每个父节点只能有两个子节点,很像一棵二叉树的结构。

牢记下面优先队列有三个重要的性质。

1.数组里的第一个元素array[0]拥有最高的优先级别。

2.给定一个下标i,那么对于元素array[i]而言:

  • 它的父节点所对应的元素下标是它的父节点所对应的元素下标是(i-1)/2
  • 它的左孩子所对应的元素下标是2×i+1
  • 它的右孩子所对应的元素下标是2×i+2

3.数组里每个元素的优先级别都要高于它两个孩子的优先级。

优先队列有两种操作:

1.向上筛选(sift up)

  • 当有新数据导入时,最先存放在二叉堆的底部。
  • 不断进行向上筛选的操作,即如果发现该数据的优先级别比父节点的优先级别还要高,那么就和父节点的元素相互交换,再接着往上进行比较,直到无法再继续交换为止。

2.向下筛选(sift down)

  • 当堆顶的元素取出后,需要将堆底部的元素放到堆顶,然后不断执行向下筛选工作。
  • 将该元素和它的两个孩子节点对比优先级,如果优先级最高的是其中一个孩子,就将该元素和那个孩子进行交换,然后反复进行下去,直到无法继续交换为止。

时间复杂度:整个过程就是沿着树的高度往下爬,所以时间复杂度也是 O(logk)。

因此,无论是添加新的数据还是取出堆顶的元素,都需要 O(logk) 的时间。

初始化
优先队列的初始化是一个最重要的时间复杂度,是分析运用优先队列性能时必不可少的,也是经常容易弄错的地方。

举例:有 n 个数据,需要创建一个大小为 n 的堆。

注意:算法面试中是不要求推导的,你只需要记住,初始化一个大小为 n 的堆,所需要的时间是 O(n) 即可。

例题分析

思路:

解这类求"前k个"的题目,关键是看如何定义优先级以及优先队列中元素的数据结构。

  • 题目中有”前k个“这样的字眼,应该很自然地联想到优先队列。优先级别可以由字符串出现的次数来决定,出现的次数越多,优先级越高。
  • 统计词频的最好数据结构就是哈希表
  • 将数和其出现的次数来作为一个新的对象来构建一个优先队列

python中标准库heapq的使用 https://www.jianshu.com/p/801318c77ab5(heapq默认支持最小堆的构建)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值