I am reading Binomial Heap
in Purely Functional Data Structures.
The implementation of insTree
function confused me quite much. Here are the set of codes
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')
My confusion lies on the bit in insTree
that why it does not consider the situation of rank t > rank t'?
In if rank t < rank t' then t::ts else insTree (link (t, t'), ts')
,
- if t's rank is less than t''s rank, then put the t into the heap, no question asked
- the else has two cases: equal and bigger.
- For equal, yes, we can link two trees (we link only two trees with the same rank), and then try to insert the new linked tree into the heap, no question asked.
- but even the bigger case would have the same as equal, why? Even if rank t > rank t', we still link them?
Edit
I thought the process of inserting a binomial tree into a binomial heap
should be like this:
- We get the tree t and the heap
- In the heap (actually a list), we compare rank of the tree t with every tree in the heap
- We find a missing rank (increasing order in the heap) which matches the rank of t, we put t at that slot
- We find a tree in the heap with same rank as t, then we link two trees and process a
rank+1
new tree and try again insert the new tree to the heap.
So, I think the correct fun insTree
could be like this:
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'))