高级数据结构—二项堆与斐波那契堆详细介绍(算法导论中科大USTC)

41 篇文章 1 订阅
40 篇文章 6 订阅

在这里插入图片描述

斐波那契堆请点击这里👈

数据结构与堆

下图列出了小顶堆在各种数据结构(链表、二叉堆、二项堆、斐波那契堆、松弛堆)的实现下,各种基本操作的时间复杂度
在这里插入图片描述

二项树

二项堆是二项树的集合。在了解二项堆之前,先对二项树进行介绍。

定义

二项树是一种递归定义的有序树。它的递归定义如下:

  1. 二项树 B 0 B_0 B0只有一个结点
  2. 二项树 B k B_k Bk由两棵二项树 B ( k − 1 ) B_{(k-1)} B(k1)组成的,其中一棵树是另一棵树根的最左孩子
    在这里插入图片描述

性质

在这里插入图片描述
[性质一]
B k B_k Bk共有 2 k 2^k 2k个节点。
如上图所示, B 0 B0 B0 2 0 = 1 2^0=1 20=1节点, B 1 B_1 B1 2 1 = 2 2^1=2 21=2个节点, B 2 B_2 B2 2 2 = 4 2^2=4 22=4个节点,…
[性质二]
B k B_k Bk的高度为 k k k
如上图所示, B 0 B_0 B0的高度为 0 0 0 B 1 B_1 B1的高度为 1 1 1 B 2 B_2 B2的高度为 2 2 2,…
[性质三]
B k B_k Bk在深度 i i i处恰好有 C ( k , i ) C(k,i) C(k,i)个节点,其中 i = 0 , 1 , 2 , . . . , k i=0,1,2,...,k i=0,1,2,...,k
C ( k , i ) C(k,i) C(k,i)是高中数学中阶乘元素,例如,
C ( 10 , 3 ) = ( 10 ∗ 9 ∗ 8 ) ( 3 ∗ 2 ∗ 1 ) = 240 C(10,3)=\cfrac{(10*9*8) }{(3*2*1)}=240 C(10,3)=(321)(1098)=240
B 4 B_4 B4中深度为 0 0 0的节点 C ( 4 , 0 ) = 1 C(4,0)=1 C(4,0)=1
B 4 B_4 B4中深度为 1 1 1的节点 C ( 4 , 1 ) = 4 / 1 = 4 C(4,1)= 4 / 1 = 4 C(4,1)=4/1=4
B 4 B_4 B4中深度为 2 2 2的节点 C ( 4 , 2 ) = ( 4 ∗ 3 ) / ( 2 ∗ 1 ) = 6 C(4,2)= (4*3) / (2*1) = 6 C(4,2)=(43)/(21)=6
B 4 B_4 B4中深度为 3 3 3的节点 C ( 4 , 3 ) = ( 4 ∗ 3 ∗ 2 ) / ( 3 ∗ 2 ∗ 1 ) = 4 C(4,3)= (4*3*2) / (3*2*1) = 4 C(4,3)=(432)/(321)=4
B 4 B_4 B4中深度为 4 4 4的节点 C ( 4 , 4 ) = ( 4 ∗ 3 ∗ 2 ∗ 1 ) / ( 4 ∗ 3 ∗ 2 ∗ 1 ) = 1 C(4,4)= (4*3*2*1) / (4*3*2*1) = 1 C(4,4)=(4321)/(4321)=1
合计得到 B 4 B_4 B4的节点分布是 ( 1 , 4 , 6 , 4 , 1 ) (1,4,6,4,1) (1,4,6,4,1)
在这里插入图片描述
[性质四]
根的度数为 k k k,它大于任何其它节点的度数。
节点的度数是该结点拥有的子树的数目。

二项堆

定义

二项堆是指满足以下性质的二项树的集合:

  1. 每棵二项树都满足最小堆性质。即,父节点的关键字 < = <= <= 它的孩子的关键字。
  2. 不能有两棵或以上的二项树具有相同的度数(包括度数为 0 0 0)。换句话说,具有度数 k k k的二项树有 0 0 0个或 1 1 1个。
    在这里插入图片描述

上图就是一棵二项堆,它由二项树 B 0 B_0 B0 B 1 B_1 B1 B 4 B_4 B4组成。对比二项堆的定义:

  1. 二项树 B 0 、 B 1 、 B 4 B_0、B_1、B_4 B0B1B4都是最小堆
  2. 二项堆不包含相同度数的二项树

性质

二项堆的第 1 1 1个性质保证了二项堆的最小节点就是某个二项树的根节点,第 2 2 2个性质则说明结点数为n的二项堆最多只有 log ⁡ n + 1 \log{n} + 1 logn+1棵二项树。实际上,将包含 n n n个节点的二项堆,表示成若干个 2 2 2的指数和(或者转换成二进制),则每一个 2 2 2个指数都对应一棵二项树。例如, 13 13 13(二进制是 1101 1101 1101)的 2 2 2个指数和为 13 = 23 + 22 + 20 13=23 + 22+ 20 13=23+22+20, 因此具有 13 13 13个节点的二项堆由度数为 3 , 2 , 0 3, 2, 0 3,2,0的三棵二项树组成。

实现

  • 使用左子级、右同级指针表示树。 每个节点三个链接:父节点、左节点(最左边的子节点)、右边(右边的同级节点)。
  • 与单链表相连的树根。 当我们遍历根链时,树的度数会严格增加。

内存

下图为二项式堆 H H H,堆由二元树 B 0 、 B 2 和 B 3 B_0、B_2 和B_3 B0B2B3组成,它们分别具有 1 、 4 和 8 1、4 和 8 148个节点
在这里插入图片描述
下图为 H H H堆的内存表示
在这里插入图片描述

N 节点二项堆的属性

  1. 最小键包含在 B 0 、 B 1 、 . . . 、 B k B_0、 B_1、... 、 B_k B0B1...Bk的根中。
  2. 包含二项式树 B i B_i Bi if   b i = 1 \ b_i = 1  bi=1,其中 b n ⋅ b 2 b 1 b 0 b_n·b_2b_1b_0 bnb2b1b0 N = ∑ i = 0 ⌊ log ⁡ N ⌋ b i 2 i N = \sum^{⌊\log N⌋}_{i= 0 }b_i2^i N=i=0logNbi2i 的二进制表示。
  3. 最多 ⌊ log ⁡ N ⌋ + 1 ⌊\log N⌋+ 1 logN+1 个二项式树。
  4. 高度 ≤ ⌊ log ⁡ N ⌋ ≤ ⌊\log N⌋ logN
    在这里插入图片描述

合并二项堆

创建堆 H ′ H ^′ H H ′′ H^{′′} H′′ 并集的 H H H(在 O ( 1 ) O(1) O(1) 时间内)

  1. 待合并的堆是“可合并堆”
  2. 如果 H ′ 和 H ′′ 各是 k 阶二项式树,则很容易。
    a. 连接 H ′ 和 H ′′ 的根
    b. 选择较小的键作为 H 的根
    在这里插入图片描述
    下面看一个更复杂的例子
    一个 B 4 、 B 2 、 B 0 B_4、B_2、B_0 B4B2B0组成的二项树与一个 B 2 、 B 1 、 B 0 B_2、B_1、B_0 B2B1B0组成的二项树相加
    在这里插入图片描述
    首先将两个 B 0 B_0 B0合并得到一个 B 1 B_1 B1
    在这里插入图片描述
    再将两个 B 1 B_1 B1合并得到一个 B 2 B_2 B2
    在这里插入图片描述
    再将两个 B 2 B_2 B2合并得到一个 B 3 B_3 B3
    在这里插入图片描述
    再将 B 3 B_3 B3
    在这里插入图片描述
    最后与 B 4 B_4 B4合并得到一个 B 4 、 B 3 、 B 1 B_4、B_3、B_1 B4B3B1组成的二项树
    在这里插入图片描述

合并操作的时间复杂度

在这里插入图片描述

  • 合并 H ′ H' H H ′ ′ H'' H′′得到堆 H H H,这个过程类似于二进制加法
  • 时间复杂度为 O ( log ⁡ N ) O(\log N) O(logN),与根链中树的数目成比例
    • ⌊ log ⁡ N ′ ⌋ + 1 + ⌊ log ⁡ N ′ ′ ⌋ + 1 ≤ 2 ( ⌊ log ⁡ N ⌋ + 1 ) ⌊\log N'⌋ + 1 + ⌊\log N''⌋ + 1≤ 2 (⌊\log N⌋ + 1) logN+1+logN′′+12(⌊logN+1)

删除最小值结点

在这里插入图片描述

  • 由于二项堆符合最小堆性质,所以
    1. H H H的根链中找到具有最小键值的根 x x x,然后删除
    2. x x x处断开,得到两个二项堆,一个为 H ′ H' H
    3. H H H H ′ H' H执行 U N I O N UNION UNION
  • 时间复杂度为 O ( log ⁡ N ) O(\log N) O(logN)

示例在这里插入图片描述在这里插入图片描述
在这里插入图片描述

Decrease key

在这里插入图片描述

  • 降低堆 H H H x x x结点的键值
    1. 对于在 B k B_k Bk中的 x x x结点
    2. 如果降低后 x x x的键值过小(破坏了最小堆属性),则将其向上冒泡
  • 时间复杂度为 O ( log ⁡ N ) O(\log N) O(logN)
    • 与结点 x x x的深度成比例,但 ≤ ⌊ log ⁡ 2 N ⌋ \le⌊\log_2N⌋ log2N

删除结点

在这里插入图片描述

  1. x x x执行 D r e a s e   k e y Drease\ key Drease key使其键值降低至 − ∞ -∞
  2. x x x执行 D E L E T E − M I N DELETE-MIN DELETEMIN
    • 时间复杂度为 O ( log ⁡ N ) O(\log N) O(logN)

插入结点

在这里插入图片描述

  1. 要插入的结点单独成为一个二项堆
  2. 将该二项堆与原二项堆执行 U N I O N UNION UNION操作
    • 时间复杂度 O ( log ⁡ N ) O(\log N) O(logN)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之墨_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值