私はOkasaki's Purely Functional Data Structuresを読んでおり、いくつかの演習をしようとしています。それらのうちの1つは、二項ヒープmerge
がO(log n)
時間かかることを証明することです。ここで、n
はヒープ内のノードの数です。二項ヒープ:O(log 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''でなければなりません。 'rs'は' ts1'' *と '' ts2''にツリーがある最小のランクとして選択されます。これらのツリーはマージされます(ランク 'r '+ 1'ツリーを形成する)ので、マージされたヒープ' merge(ts1'、ts2 ') 'では、ランクrのツリーはもはや存在しません。前の 'insTree'の呼び出しは、いくつかのランク(つまり、' ts1 'または 'ts2'のいずれかがそのようなランクのツリーを含んでいる限り)で再帰することができますが、この再帰はランク' r ''。また、 'merge'からの' insTree'の次の呼び出しは 'r '+ 1'ランクで行われます。したがって、 'insTree'は各ランクに対して最大で1回呼び出されます。 – m7thon