📜  二项式堆

📅  最后修改于: 2021-04-17 11:46:46             🧑  作者: Mango

二进制堆的主要应用是作为实现优先级队列。 Binomial Heap是Binary Heap的扩展,可提供更快的合并或合并操作以及Binary Heap提供的其他操作。

二项式堆是二项式树的集合

什么是二叉树?
顺序为0的二叉树有1个节点。可以通过采用k-1阶的两个二叉树并将一个作为最左子级或另一个作为二阶树来构建k阶的二叉树。
k阶二叉树具有以下属性。
a)它正好有2 k个节点。
b)深度为k。
c)对于i = 0,1,,在深度i处恰好有k个C i个节点。 。 。 ,k。
d)根的度数为k,根的子代本身就是二项式树,从左到右依次为k-1,k-2,.. 0。

k = 0 (Single Node)

 o

k = 1 (2 nodes) 
[We take two k = 0 order Binomial Trees, and
make one as child of other]
  o
 /  
o     

k = 2 (4 nodes)
[We take two k = 1 order Binomial Trees, and
make one as child of other]
     o
   /   \
  o     o
 /       
o        

k = 3 (8 nodes)
[We take two k = 2 order Binomial Trees, and
make one as child of other]
      o   
   /  | \ 
  o   o  o
 / \  | 
o   o o   
     \           
      o         

下图是从第二版CLRS书中引用的。

二叉树

二项式堆:
二项式堆是一组二项式树,其中每个二项式树都遵循“最小堆”属性。最多可以有一个任何程度的二叉树。

二项式堆的示例:

12------------10--------------------20
             /  \                 /  | \
           15    50             70  50  40
           |                  / |    |     
           30               80  85  65 
                            |
                           100
A Binomial Heap with 13 nodes. It is a collection of 3 
Binomial Trees of orders 0, 2 and 3 from left to right. 

    10--------------------20
   /  \                 /  | \
 15    50             70  50  40
 |                  / |    |     
 30               80  85  65 
                  |
                 100

具有12个节点的二项式堆。它是2的集合
从左到右顺序为2和3的二叉树。

数字和二项式堆的二进制表示
具有n个节点的二项式堆的二叉树的数量等于n的二进制表示形式中的设置位的数量。例如,假设n为13,则在n的二进制表示中有3个设置位(00001101),因此有3个二叉树。我们还可以将这些二叉树的程度与设置位的位置相关联。通过这种关系,我们可以得出结论,在具有“ n”个节点的二项式堆中有O(Logn)个二叉树。

二项式堆的操作:
二项式堆中的主要操作是union(),所有其他操作主要使用此操作。 union()操作是将两个二项式堆合并为一个。让我们首先讨论其他操作,稍后再讨论联合。

  1. insert(H,k):将键“ k”插入二项式堆“ H”。此操作首先创建具有单键“ k”的二项式堆,然后在H和新的二项式堆上调用并集。
  2. getMin(H):一种简单的getMin()方法是遍历二叉树的根列表并返回最小键。此实现需要O(Logn)时间。可以通过维护指向最小密钥根的指针来将其优化为O(1)。
  3. extractMin(H):此操作还使用union()。我们首先调用getMin()来找到最小键二项式树,然后删除该节点,并通过连接删除的最小节点的所有子树来创建一个新的二项式堆。最后,我们在H和新创建的Binomial Heap上调用union()。此操作需要O(Logn)时间。
  4. delete(H):与Binary Heap一样,delete操作首先将键减小为负无穷大,然后调用extractMin()。
  5. reductionKey(H):reductionKey()也类似于Binary Heap。我们将减少键与它的父键进行比较,如果父键的键更多,则交换键并为父键递归。当到达父节点的键较小的节点或击中根节点时,我们将停止。 reductionKey()的时间复杂度为O(Logn)。

    二项式堆中的联合操作:
    给定两个二项式堆H1和H2,union(H1,H2)创建一个单个二项式堆。

  6. 第一步是简单地以非降序合并两个堆。在下图中,图(b)显示了合并后的结果。
  7. 简单合并后,我们需要确保最多有一个任意顺序的二叉树。为此,我们需要组合相同顺序的二叉树。我们遍历合并根的列表,我们跟踪三个指针,prev,x和next-x。当遍历根目录列表时,可能有以下4种情况。
    —情况1:x和next-x的顺序不相同,我们只是继续前进。
    在以下3种情况下,x和next-x的顺序相同。
    —情况2:如果next-next-x的顺序也相同,请继续。
    —情况3:如果x的键小于或等于next-x的键,则通过将其与x链接,使next-x成为x的子代。
    案例4:如果x的键更大,则使x成为next的子代。

    下图取自《 CLRS》第二版。

二项式堆联合

如何表示二项式堆?
二项式堆是一组二项式树。一棵二叉树必须以一种允许从最左侧的同级开始顺序访问所有同级的方式表示(我们需要in和extractMin()和delete())。想法是将二项式树表示为最左侧的子级和右侧同级表示,即,每个节点存储两个指针,一个指向最左侧的子级,另一个指向右侧同级。

二项式堆的实现

资料来源:
Clifford Stein,Thomas H.Cormen,Charles E.Leiserson,Ronald L.