我正在阅读Okasaki's Purely Functional Data Structures并正在尝试做一些练习。其中之一是证明二项式堆merge
需要O(log n)
时间,其中n
是堆中的节点数。Binomial堆:证明合并运行在O(日志n)时间
functor BinomialHeap (Element:ORDERED):HEAP=
struct
structure Elem=Element
datatype Tree = Node of int*Elem.T*Tree list
type Heap = 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 insTree (t,[])=[t]
|insTree (t,ts as t'::ts')=
if rank t < rank t' then t::ts else insTree(link(t,t'),ts')
fun insert (x,ts)=insTree(Node(0,x,[]),ts) (*just for reference*)
fun merge (ts1,[])=ts1
|merge ([],ts2)=ts2
|merge (ts1 as t1::ts1', ts2 as t2:ts2')=
if rank t1 < rank t2 then t1::merge(ts1',ts2)
else if rank t2 < rank t1 then t2::merge(ts1,ts2')
else insTree (link(t1,t2), merge (ts1',ts2'))
end
显然,merge
将调用自身max(numNodes ts1, numNodes ts2)
倍,但由于insTree
是O(log n)
最坏的情况下,你可以解释如何merge
是O(log n)
?
你可以扩展这个:“但是,合并堆'merge(ts1',ts2')'因此不能包含一个等级<='r''”的树。我相信如果'ts1'有一棵等级为“r”的树并且'ts2'不包含'r''的树。 –
忘记“<='r''”,如果应该只是'r'(只是固定的)。 'r''被选为'ts1'' *和*'ts2''中树的最小等级。这些树被合并(形成一个等级'r'+ 1'树),所以在合并堆merge(ts1',ts2')'中,不再有一个等级为“r”的树。之前对'insTree'的调用可以缓解一些等级(也就是说,只要'ts1'或'ts2'包含这样一个等级的树),但是这个递归必须停止在'r'级“'。另外,下一次从'merge'调用'insTree'出现在'r'+ 1'级。所以'insTree'每个级别最多被调用一次。 – m7thon