我正在閱讀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