优先队列(堆)·二项队列

目录

  • 一、 定义
  • 二、 结构
  • 三、 操作
    • 3.1、 合并
    • 3.1、 删除最小值(deleteMin)
  • 四、 二项队列的实现
  • 代码地址

一、 定义

? 我们知道,左式堆每次操作的时间界是\(O(logN)\)。二项队列支持合并、插入、删除最小值,每次插入的平均时间为常数时间,而最坏时间是\(O(logN)\)。

? 二项队列:

  • 不是一棵堆序的树,而是堆序的树的集合,成为森林
  • 森林的每棵树都是二项树(binomial tree)
  • 每个高度上至多存在一棵二项树。

二、 结构

? 结构图解:

?

  1. 高度为0的二项树是一棵单节点树,例如B0
  2. 高度为k的二项树\(B_k\)通过将一棵二项树\(B_{k-1}\)附接到另一棵二项树\(B_{k-1}\)的根上而构成。

? 结构描述:如上图

? 二项树\(B_{k}\)由一个带有儿子\(B_{0}\),\(B_{1}\),\(B_{2}\),…,\(B_{k-1}\)的根组成!高度为k的二项树恰好有\(2^k\)个节点,而在深度\(d\)处的节点数是二项系数\(\binom{k}{n}\)。如果我们把堆序施加到二项树上并允许任意高度最多一棵二项树,那么就能够用二项树的集合表示任意大小的优先队列。例如大小为13的优先队列可以用森林\(B_3\),\(B_2\),\(B_0\)表示。可以记作1101,它不仅使用二进制表示了13的大小,而且也表达了这样的事实:在上述表示中,\(B_3\),\(B_2\),\(B_0\)出现,而\(B_1\)没有。

二项树组成的森林根二进制的关系:

数字13:森林表示为\(B_3\),\(B_2\),\(B_0\);二进制记录为1101。

数字10:森林表示为\(B_3\),\(B_1\);二进制记录为1010。

三、 操作

? 二项队列中,最小元可以通过森林中所有的的树的根来找出。由于最多有\(logN\)棵不同的树,因此找到最小元的时间可以为\(O(logN)\)。如果我们记住最小元,并且在每次操作时更新它,那么可以直接操作最小元,时间为\(N\)。

3.1、 合并

? 合并两个二项队列在概念上是一个容易的操作。如下合并H1和H2。

? 合并图解:

  1. 令\(H_3\)是新的二项队列,由于\(H_1\)没有高度为0的树而\(H_2\)有,我们让\(H_2\)中高度为0的树作为\(H_3\)的一部分。然后将两个高度为1的二项树相加。
  2. 将\(H_1\)和\(H_2\)的高度为1的二项树相加,让大的根成为小的根的子树,从而建立高度为2的二项树。
  3. 现在存在3棵高度为2的树,我们将合并其中2棵树,建立高度为3的二项树,这样,就只存在一棵高度为2,一棵高度为3,一棵高度为0的树组成的森林。

合并分析

? 几乎使用任意合理的实现方法合并2棵树均花费常数时间,而总共存在\(O(lonN)\)棵二项树,因此合并操作的最坏情形时间\(O(logN)\)。

关于时间界\(O(logN)\)

在N个节点组成的二项队列森林中,每个高度有且只有一棵树,很明显,高度\(h = logN\),而合并操作本身花费常数时间,总个数\(O(logN)\)。很容得到以上时间界。

?

? 关于插入,插入其实就是合并一棵高度为0的二项树。关于插入的合并次数,如果元素将要插入的那个优先队列中不存在的最小二项树是\(B_i\),那么运行时间与\((i+1)\)成正比

关于插入的时间界:

为什么是\((i+1)\)的正比呢。假设:那么插入一个元素当作合并一个高度为0的二项树,记作\(C_0\);

\(i = 1\):森林中不存在\(B_1\),那么最小树则是\(B_0\),那么只需要合并\(B_0\)和\(C_0\)就能得到一棵高度为1的树,作为\(B_1\)。

\(i = 2\):森林中不存在$B_2 \(,那么最小树则是\)B_1 \(,第一次发生在\)B_0\(和\)C_0\(,得到\)C_1\(。第二次合并发生在\)B_1\(和\)C_1\(,得到\)B_2$。

依次类推,我们可以知道\(i\)就是需要合并的次数。而1是插入时间。得到上述时间描述。

3.1、 删除最小值(deleteMin)

? 由于我们的二项队列中所有的二项树,均是堆序的。所以我们只需要比较所有树的根节点,就能找到最小值。关键在于,我们删除一棵高度为\(k\)的树的根节点,那么棵树会降级为多棵树,此时会打乱森林的顺序,我们需要重新整理森林里的树,重新得到二项队列。

? 删除图解:

  1. 删除二项队列H3中的最小值12,那么由H3解体得到\(H3-2\),和原来的高度为0和1的树得到的\(H3-2\)。
  2. 得到2个二项队列:\(H3-1\),\(H3-2\)。现在要做的就是将这个队列合并
  3. 根据上文的合并法则,得到\(H4\)。
  4. 删除最小值本质上就是组建二项堆+合并二项堆。所以时间界依然是\(O(logN)\)。

    关于这个时间界:

    我们知道只要量级为改变,在大O模型中单纯的加减是不会影响我们对于时间算法的估计的。

四、 二项队列的实现

? 最重要的操作是deleteMin和merge。deleteMin需要快速找到最小值,因此需要一般树的标准表示方法。该操作还要求各个儿子按照他们的子树的大小排序。

? 合并树是我们需要将一棵树作为另一棵树的儿子被加到另一棵树上。由于这颗心树将是最大的子树,因此,以大小递减的方式保持这些子树是最好的。

? 实现方法:

  • 二项树的每一个节点将包含数据、第一个儿子以及右兄弟
  • 二项树中的各个儿子降秩次序排列。

    如图:

代码地址

....

原文地址:https://www.cnblogs.com/dhcao/p/10639652.html

时间: 2024-11-05 11:35:45

优先队列(堆)·二项队列的相关文章

优先队列——二项队列(binominal queue)

[0]README 0.1) 本文文字描述部分转自 数据结构与算法分析, 旨在理解 优先队列——二项队列(binominal queue) 的基础知识: 0.2) 本文核心的剖析思路均为原创(insert,merge和deleteMin的操作步骤图片示例), 源代码均为原创: 0.3) for original source code, please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree

二项队列

二项队列是 堆序 的集合,也叫 森林.其中每一种形式都有约束. 二项树Bk由一个带有儿子的B0,B1,B2...组成,高度为k的二项树 恰好有2^k个结点.每一种高度只能出现一次...因此,只有1,2,4,8...等结点数目的二项树 deleteMin操作需要快速的找出跟的所有子树的能力,因此需要一般树的表示方法: 每个结点的儿子都在一个链表中,而且每个结点都有一个指向它的第一个儿子的指针. 二项树的每一个结点包括:数据,第一个儿子,以及右兄弟 下面是二项队列类构架及结点定义: 1 templa

数据结构--二项队列的思想与实现

二项队列不是一颗堆序的树,而是堆序树的集合,称为森林,森林中每棵树都是有约束的形式,称为二项树,高度为k的第k个二项树Bk由一个根节点和B0, B1, .......B(k-1)构成,高度为k的二项树的结点个数为2^k,因此可以用二项树的结合表示任意大小的优先队列.例如,大小为13的优先队列就可以用B3,B2,B0来表示,2^0+2^2+2^3 = 13.因此二进制的表示为1101. 例如,二项树B0,B1,B2,B3表示如下: 把所有二项树的根节点按规律放在一个根节点组成的数组中,就组成二项队

转载:数据结构 二项队列

0)引论 左堆的合并,插入,删除最小的时间复杂度为O(logN).二项队列就是为了对这些结果进一步提高的一种数据结构.利用二项队列,这三种操作的最坏时间复杂度为O(logN),但是插入的平均时间复杂度为O(1). 1)二项队列 二项队列不是一棵树,它是一个森林,由一组堆序的树组成的深林,叫做二项队列. 二项队列有几个性质比较重要 (a) 每一颗树都是一个有约束的堆序树,叫做二项树 (b) 高度为k的第k个二项树Bk由一个根节点和B0, B1, .......B(k-1)构成 (c) 高度为k的二

二项队列———数据结构与算法分析第二版(C)

引论 左堆的合并,插入,删除最小的时间复杂度为O(logN).二项队列就是为了对这些结果进一步提高的一种数据结构.利用二项队列,这三种操作的最坏时间复杂度为O(logN),但是插入的平均时间复杂度为O(1) 二项队列 二项队列不是一棵树,它是一个森林,由一组堆序的树组成的深林,叫做二项队列. 二项队列有几个性质比较重要 (a) 每一颗树都是一个有约束的堆序树,叫做二项树 (b) 高度为k的第k个二项树Bk由一个根节点和B0, B1, .......B(k-1)构成 (c) 高度为k的二项树的结点

数据结构--二项队列分析及实现

一,介绍 什么是二项队列,为什么会用到二项队列? 与二叉堆一样,二项队列也是优先级队列的一种实现方式.在 数据结构--堆的实现之深入分析 的末尾 ,简单地比较了一下二叉堆与二项队列. 对于二项队列而言,它可以弥补二叉堆的不足:merge操作的时间复杂度为O(N).二项队列的merge操作的最坏时间复杂度为O(logN). 二,二项队列的基本操作及实现 在详细介绍二项的队列的基本操作之前,先了解下二项队列这种数据结构: 1)一个二项队列是若干棵树的集合.也就是说,二项队列不仅仅是一棵树,而是多棵树

二项队列的查找插入合并操作

源码例如以下: /* <span style="color:#ff0000;">一棵二次幂堆</span>是一棵左有序的堆,由右子树为空左子树为全然二叉树构成的根组成 <span style="color:#ff0000;">二项队列</span>:是二次幂堆的一个集合. 当中不存在相等大小的堆.其结构由队列节点数目确定 相应整数的二进制表示. */ #include <stdlib.h> #include

[硕.Love Python] BinomialHeap(B堆 & 二项堆)

class Node(object):     def __init__(self, data):         self.data = data         self.child = None         self.left = None         self.right = None         self.degree = 0     def __str__(self):         return str(self.data)     __repr__ = __str_

笔试算法题(46):简介 - 二叉堆 &amp; 二项树 &amp; 二项堆 &amp; 斐波那契堆

二叉堆(Binary Heap) 二叉堆是完全二叉树(或者近似完全二叉树):其满足堆的特性:父节点的值>=(<=)任何一个子节点的键值,并且每个左子树或者右子树都是一 个二叉堆(最小堆或者最大堆):一般使用数组构建二叉堆,对于array[i]而言,其左子节点为array[2*i],其右子节点为 array[2*i+1]:二叉堆支持插入,删除,查找最大(最小)键值的操作,但是合并二叉堆的复杂度较高,时间复杂度为O(N):但是二项堆或者斐波 那契堆则仅需要O(logN): 二项树(Binomial