数据结构与算法之美
王争
前 Google 工程师
283752 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 81 讲
基础篇 (38讲)
数据结构与算法之美
15
15
1.0x
00:00/00:00
登录|注册

29 | 堆的应用:如何快速获取到Top 10最热门的搜索关键词?

分片处理
利用堆求Top 10
统计关键词频率
时间复杂度
解决方法
时间复杂度
解决方法
时间复杂度
解决方法
实时Top K
时间复杂度
解决方法
最小生成树算法
图的最短路径
赫夫曼编码
内存限制
解决思路
问题描述
动态数据集合
静态数据集合
针对动态数据集合
针对静态数据集合
应用场景
实现方法
概念
实现新闻网站首页banner的Top 10新闻摘要滚动显示功能
内容小结
获取Top 10最热门的搜索关键词
求中位数问题
求Top K问题
优先级队列
课后思考
解答开篇
堆的应用

该思维导图由 AI 生成,仅供参考

搜索引擎的热门搜索排行榜功能你用过吗?你知道这个功能是如何实现的吗?实际上,它的实现并不复杂。搜索引擎每天会接收大量的用户搜索请求,它会把这些用户输入的搜索关键词记录下来,然后再离线地统计分析,得到最热门的 Top 10 搜索关键词。
那请你思考下,假设现在我们有一个包含 10 亿个搜索关键词的日志文件,如何能快速获取到热门榜 Top 10 的搜索关键词呢?
这个问题就可以用堆来解决,这也是堆这种数据结构一个非常典型的应用。上一节我们讲了堆和堆排序的一些理论知识,今天我们就来讲一讲,堆这种数据结构几个非常重要的应用:优先级队列、求 Top K 和求中位数。

堆的应用一:优先级队列

首先,我们来看第一个应用场景:优先级队列。
优先级队列,顾名思义,它首先应该是一个队列。我们前面讲过,队列最大的特性就是先进先出。不过,在优先级队列中,数据的出队顺序不是先进先出,而是按照优先级来,优先级最高的,最先出队。
如何实现一个优先级队列呢?方法有很多,但是用堆来实现是最直接、最高效的。这是因为,堆和优先级队列非常相似。一个堆就可以看作一个优先级队列。很多时候,它们只是概念上的区分而已。往优先级队列中插入一个元素,就相当于往堆中插入一个元素;从优先级队列中取出优先级最高的元素,就相当于取出堆顶元素。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

堆是一种重要的数据结构,在本文中介绍了堆的几个重要应用场景。首先,堆可以用于实现优先级队列,对于处理优先级较高的数据具有很大帮助。其次,堆可以高效地解决求Top K和中位数等问题,无论是对于静态数据集合还是动态数据集合。文章通过具体的例子生动地展示了堆的实际应用,如合并有序小文件和高性能定时器。此外,文章还介绍了利用哈希算法对大数据进行分片处理的方法,以解决内存限制的问题。总之,本文通过实际例子和详细解释,使读者能够快速了解堆的应用和实现方法,为解决实际问题提供了重要的帮助。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《数据结构与算法之美》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(240)

  • 最新
  • 精选
  • oatlmy
    老师,请问为什么评价算法性能是根据时间和空间复杂度,而不是别的参数?是因为计算机结构是冯诺依曼体系,除了输入输出设备和控制器,就剩下运算器和存储器了吗?

    作者回复: 你理解的没错

    2018-11-28
    2
    125
  • Miletos
    “如果新加入的数据小于等于大顶堆的堆顶元素,我们就将这个新数据插入到大顶堆;如果新加入的数据大于等于小顶堆的堆顶元素,我们就将这个新数据插入到小顶堆。” 1. 这里不太对劲,前文中说到,小顶堆的堆顶大于大顶堆的堆顶。 如果新进元素在小顶堆堆顶和大顶堆堆顶元素值之间,没有规定插入哪个堆。 我觉得,是不是只要判断一次就可以了。新进元素值大于等于小顶堆堆顶元素的,插入小顶堆,否则插入大顶堆。 当某一个堆数据过多时再重新移动堆顶元素。 2. 求中位数的源数据中,是否允许重复数据?

    作者回复: 1 你说的对 我改下 多谢指正 2 可以重复

    2018-11-28
    4
    105
  • 豪华
    老师,分片求取前十是不是有bug,如果有一个关键词在每一组分片中都是前第十一位,在整个十亿中个数总和是第一位,是不是用分片求出了错误的结果呢?

    作者回复: 不会的 相同的关键词经过哈希之后只会到一台机器

    2018-11-28
    6
    34
  • Aaaaaaaaaaayou
    topK 是不是应该先要填满堆,后面插入的时候再做删除操作

    作者回复: 是的。

    2019-02-20
    2
    31
  • geraltlaush
    之前遇到qq的一个面试题,一个用户的登录了qq,如果五分钟内用户没有检测到心跳包,就需要用户重新登录,登录后重新计时五分钟,是不是也用高等计时器来管理海量用户的计时登录问题,把qq号和时间五分钟当成堆节点,有心跳来就调整堆,把五分钟规定时间剩下最少的用户放在堆顶,后台线程每次扫描的时候取堆顶元素,然后计算剩余的等待时间,等规定时间到了,就取堆顶元素,判断是否为0,如果为0,就需要重新登录,一直取堆顶,直到取到不为0的元素,然后计算剩余等待时间,线程休眠,等到了规定时间再来,老师你看这个方案可行不

    作者回复: 赞,可行。

    2019-07-26
    10
    28
  • ZX
    看了这一章,发现堆删除任意元素这个方法毫无意义啊。只有删除堆顶元素才有意义

    作者回复: 是的啊 没有说过删除任意元素呢

    2018-12-02
    4
    25
  • 蚂蚁内推+v
    数据是动态的,为什么不能用数组呢?我们维护一个size为k的有序数组(用快排,复杂度是klogk,插入法建堆也是klogk),然后每来一个元素,就把数组的第一个元素比较,如果大就插入,如果小就舍弃。插入使用二分,也是logn。没感觉堆有什么好处啊?老师

    作者回复: 维护数组有序的话,你用二分是可以查找的元素要插入的位置,但真正插入这个元素到这个位置的时候,你得搬移数据腾空间啊,这个复杂度就是O(n)了。 建堆虽然耗时,那只需要建一次堆,之后插入数据,只需要logk的时间复杂度的

    2019-08-28
    6
    19
  • 小花小黑的铲屎官
    我们遍历这 10 亿个关键词,并且通过某个哈希算法对其求哈希值,然后哈希值同 10 取模,得到的结果就是这个搜索关键词应该被分到的文件编号。 这样并不能保证每个文件都是一亿条数据吧?可能多也可能少吧?

    作者回复: 是的 你说的没错

    2018-12-14
    14
  • Allen
    高性能定时器,使用堆数据结构不一定是最优解,“环形队列”也许更好一点

    作者回复: 👍 各有利弊吧

    2018-12-18
    11
  • 攻城拔寨
    如果我要1%到99%响应时间,这样建的堆就有点多了

    作者回复: 这需求...具体问题具体分析吧

    2018-12-09
    11
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部