在二项式堆上纠正功能

时间:2013-10-31 10:46:15

标签: data-structures functional-programming sml purely-functional binomial-heap

我正在Purely Functional Data Structures中阅读Binomial Heap

insTree函数的实现让我非常困惑。以下是代码集

datatype Tree = Node of int * Elem.T * Tree list

fun link (t1 as Node (r, x1, c1), t2 as Node (_, x2, c2)) = 
  if Elem.leq (x1, x2) then Node (r+1, x1, t2::c1)
  else Node (r+1, x2, t1::c2)

fun rank (Node (r, x, c)) = r

fun insTree (t, []) = [t]
  | insTree (t, ts as t' :: ts') =
      if rank t < rank t' then t::ts else insTree (link (t, t'), ts')

我的困惑在于insTree中的一点为什么它不考虑等级t的情况&gt;排名t&#39;

if rank t < rank t' then t::ts else insTree (link (t, t'), ts')

  1. 如果t的排名 比排名低,那么就把t放入堆中,不要问问
  2. else 有两种情况:相等更大
  3. 对于相等,是的,我们可以链接两棵树(我们只链接两个具有相同等级的树),然后尝试将新的链接树插入堆中,毫无疑问。< / LI>
  4. 但即使更大的情况也会相同,为什么?即使等级t&gt;排名t&#39;,我们仍然链接他们?

  5. 修改

    我认为inserting a binomial tree into a binomial heap的过程应该是这样的:

    1. 我们得到了树t和堆
    2. 在堆(实际上是一个列表)中,我们将树t的排名与堆中的每个树进行比较
    3. 我们发现缺少排名(堆中增加的顺序)与t的排名匹配,我们把t放在那个位置
    4. 我们在堆中找到一个与t相同的树,然后我们链接两棵树并处理一个rank+1新树,然后再次尝试将新树插入堆中。
    5. 所以,我认为正确的fun insTree可能是这样的:

      fun insTree (t, []) = [t]
            | insTree (t, ts as t' :: ts') =
                if rank t < rank t' then t::ts 
                else if rank t = rank t' then insTree (link (t, t'), ts')
                else t'::(insTree (t, ts'))
      

2 个答案:

答案 0 :(得分:1)

insTree是一个用户不可见的辅助函数。用户调用insert,后者又调用insTree和0级树,以及排名增加的树列表。 insTree具有一个不变量,即t的等级是&lt; =列表中第一棵树的等级。所以如果它不是&lt;,那么它必须是=。

你是对的,如果insTree是一个通用的公共功能,而不是一个特殊用途的私人功能,那么就必须处理丢失的情况。

答案 1 :(得分:0)

  

这背后的一个重要细节是二项式堆不是碰巧有k个孩子的任何树。这是一棵严格定义为

的树      

0阶的二叉树是单个节点,和       n阶二叉树是一个单个节点,其子序列树的顺序为0,1,2,...,n - 1作为子节点。

这个answer,解释为什么插入函数(构造二项式堆所需的函数)不管理这些情况(理论上它们不可能发生)。也许您提出的案例对合并操作有意义(但底层实现应该有所不同)。