看图说话之二叉堆(优先队列)——原理解析

一丶优先队列简介

    优先队列更多的是一种逻辑上和业务上的设计。队列中的每项元素都分配一个优先权值,队列的出队顺序按照优先权值来划分,高优先权先出队或者低优先权先出队。这样一个优先队列必须具备两个最基本的操作——入队,以及高(低)优先权出队。优先队列在很多场景中都有运用,比如打印机的任务调度和操作系统中的进程调度都有用到优先队列的设计。


图1 优先队列的两个基本功能

    此时我们假设并不知道有堆这样的数据结构,想实现上述这样的功能,其实也可以有多种解决方案,比如以下两种:

  • 构建一个链表操作,入队操作等效于在表头以0(1)的时间完成插入操作,出队操作等效于遍历链表删除最大(最小)节点时间消耗在O(N)。这样的设计保证入队操作是常数,出队操作是线性。

  • 构建一个链表,插入的过程中,始终保持链表是有序排列的(插入排序),这样入队操作的时间消耗是0(N),出队操作,就是删除链表头元素,时间消耗为0(1)。
        假如采用这种设计,入队操作多于出队的情况下选择(1),反之选择(2)。此时注意到,无论是哪种设计,入队/出队总有一个操作是线性时间消耗,在大数据的条件下,设计一种更加高效率数据结构完成优先队列的设计主必要的——二叉堆就是以O(logn)的时间复杂度完成出队和入队操作的优先队列设计。下面详细的介绍堆这种数据结构的原理和实现

二丶二叉堆的性质

    二叉堆如其名字一样和二叉树具有紧密的关系。二叉堆是一种特殊的二叉树,是对一般的二叉树提出了结构性和堆序性的要求,这种特殊结构性和堆序性是二叉堆的性质所在。

1.结构性:二叉堆是一个完全二叉树

2.堆序性:所有的节点值均小于(大于)其后裔节点值,若所有节点值大于其后裔节点这样的二叉堆称为大根堆##点值均小于其后裔节点这样的二叉堆成为小根堆。


图2 小根堆

图3大根堆

    这里可以看到,假如是小根堆的情况,那么每次取堆顶的元素,就完成了按低优先级出队的功能。若是大根队取堆顶的元素则完成按高优先级出对的顺序。
    这里需要特别注意就是,每次的出队操作=返回堆顶元素+删除堆顶元素,每次删除堆顶元素之后,需要保证依旧满足二叉堆的结构性和对堆序性,这个删除和调整的过程称为堆调整。
    下面以大根堆为例进行介绍一次堆调整,并且分析其时间复杂度为什么是O(logN)。下文描述中,堆的删除操作=优先队列的出队,堆的插入操作=优先队列的入队。

三丶大根堆的出队操作
  1. 拷贝堆顶元素,此时拷贝后的堆顶元素即为最后出队将返回为元素。


    图4 拷贝出队元素
  2. 二叉堆,删除一个元素后,堆顶的位置就空闲下来了,同时需要保持二叉堆的结构特性不变,所以二叉堆最后一个元素必须要移动,而且堆顶的空闲必须要被填补。最简单做法就是利用二叉堆的最后一个元素去填补堆顶的元素,结果如图


    图5堆尾元素填补堆顶。
  3. 观察图5此时的二叉堆情况,可以发现二叉堆的结构特性已经满足了,但是其堆序特性被破坏了。元素6是小于其左节点10和节点15的,所以调整此时二叉堆的堆序是要处理的工作,比较自身节点值,左节点值,和右节点值,取三者中的最大值替代自身,结果如下图所示。


    图6第一次堆调整结果
  4. 观察图6第一次堆调整完后的情况,可以发现元素6的左节点和右节点依然不满足堆序的特性。需要继续调整,调整方法如步骤3,调整结果如下图所示。


    图7第二次堆调整结果
  5. 第二次调整后,发现元素6是叶子节点了,调整结束。此时观察图7的二叉堆发现此时不仅满足二叉堆的结构特性,同时所有的节点都满足了堆序的特性。
  6. 最后将copy的出队值20返回,则完成了一次二叉堆的删除操作,同时也是一次优先队列的出队操作。
总结:
  • 从上面步骤1到步骤6可以归纳出,删除操作的核心就是将堆尾的元素通过不断的堆调整,将其放置到合适的位置,以满足堆序特性。

  • 堆尾的元素是在根节点通过一步步的比较,然后找到的合适位置,可以看到该元素是一层层的往下走,这个过程形象的称为“下滤”。

  • 在上述的例子中下滤过程的结束是因为已经下滤到叶子节点了,除此之外如果在下滤的过程中发现其左右节点的值均小于自身(满足堆序特性)那么下滤过程同样结束。

  • (4).一次堆删除操作(出队),是从根节点开始下滤,下滤过程中经过的路径长度决定时间的消耗,对于二叉堆来说,其是完全二叉树,若节点数为N,则高度不超过过logN,所以出队操作的时间消耗最大为O(logN),即最坏时间复杂度。

四丶大根堆的入队操作

    上文介绍了大根堆的出队操作,其时间复杂度在O(logN),此处介绍大根堆的入队操作,入队操作和出队操作和其相似,最坏时间复杂度也是O(logN)。下面将通过图例的形式分析大根堆的入队操作,假设插入元素是19。

    
图8 大根堆初始状况

1.在插入的过程中,也要保持结构性和堆序性,那么从结构性的角度来看,插入的元素19只能放在末尾,如下图所示。
图9 入队调整堆结构

2.如图9所示,在插入元素之后二叉堆的结构特性已经满足了,下面主要需要调整堆序特性。对于元素19而言,找到其父亲元素8,判断堆序性,发现19大于8,所以交换19和8的位置,结果如下。


图10入队调整堆序特性。

3.在经过上述的调整之后,发现元素19比其父亲元素大,依然不满足堆序特性,继续重复步骤2的堆序调整,结果如下:
图11 入队调整堆序特性

4.经过步骤2和步骤3的调整之后,发现19小于其父元素20了,已经满足堆序特点了,那么调整结束,此次入队操作完成。
总结:
  • 二叉堆入队操作和二叉堆出队操作有很多相似的地方,二叉堆出队操作形象的描述为“下滤”,那么入队的操作从上述的过程中来看可以描述为“上滤”。

  • 二叉堆的入队操作,上滤过程的起点是叶子节点,终点是根节点,所以其走过的路径依然是其主要的时间消耗,其走过的最大路径是二叉树的高度,所以其时间复杂度也是O(logN)。

Reference:
[1] 数据结构与算法 java语言描述版
[2] 博客原文

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容