我正在阅读Binomial Heap
Purely Functional Data Structures。
函数的实现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
为什么它不考虑 rank t > rank t' 的情况?
在if rank t < rank t' then t::ts else insTree (link (t, t'), ts')
,
- 如果 t 的排名小于t 的排名,则将 t 放入堆中,不问任何问题
- else有两种情况:等于和更大。
- 对于equal,是的,我们可以链接两棵树(我们只链接两个具有相同等级的树),然后尝试将新链接的树插入堆中,没有问题。
- 但即使是更大的情况也会有相同的平等,为什么?即使 rank t > rank t',我们仍然链接它们吗?
编辑
我认为的过程inserting a binomial tree into a binomial heap
应该是这样的:
- 我们得到树 t 和堆
- 在堆(实际上是一个列表)中,我们将树 t 的排名与堆中的每棵树进行比较
- 我们找到一个与 t 的等级相匹配的缺失等级(堆中的递增顺序),我们将 t 放在那个位置
- 我们在堆中找到一棵与 t 具有相同等级的树,然后我们链接两棵树并处理一棵
rank+1
新树并再次尝试将新树插入堆中。
所以,我认为正确的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'))