4

Purely Functional Data Structures (page 22)での Okasaki の実装は、2 つの部分でそれを行います。1 つはフォレストをマージし、もう 1 つはキャリーを伝播します。これは、ワンパスバージョンよりも分析が難しく、おそらく遅いと思います。何か不足していますか?

岡崎の実装:

ファンクター BinomialHeap (要素:ORDERED):HEAP=
構造体
  構造 Elem=要素
  datatype Tree = int*Elem.T*Tree リストのノード
  タイプ ヒープ = ツリー リスト
  fun link (ノード (r,x1,c1) としての t1、ノード (_,x2,c2) としての t2)=
    if Elem.leq(x1,x2)
    ノード (r+1,x1,t2::c1)
    else ノード (r+1,x2,t1::c2)
  fun insTree (t,[])=[t]
     |insTree (t,ts as t'::ts')=
        ランク t < ランク t' の場合 t::ts でなければ insTree(link(t,t'),ts')
  fun insert (x,ts)=insTree(Node(0,x,​​[]),ts) (*参照用*)
  楽しいマージ (ts1,[])=ts1
     |マージ ([],ts2)=ts2
     |マージ (t1::ts1' としての ts1、t2:ts2' としての ts2)=
        ランク t1 < ランク t2 の場合 t1::merge(ts1',ts2)
        そうでなければランク t2 < ランク t1 なら t2::merge(ts1,ts2')
        else insTree (link(t1,t2), merge (ts1',ts2'))
終わり

すべてのキャリーを伝搬するコストの上限を証明する必要があるため、これを分析するのは難しいと思います (以下を参照)。私が思いついたトップダウン マージの実装は、明らかに O(log n) です。ここで、n はより大きなヒープのサイズです。

ファンクター BinomialHeap (要素:ORDERED):HEAP=
構造体
  構造 Elem=要素
  datatype Tree = int*Elem.T*Tree リストのノード
  タイプ ヒープ = ツリー リスト
  楽しいランク (Node(r,_,_))=r
  fun link (ノード (r,x1,c1) としての t1、ノード (_,x2,c2) としての t2)=
    if Elem.leq(x1,x2)
    ノード (r+1,x1,t2::c1)
    else ノード (r+1,x2,t1::c2)
  fun insTree (t,[])=[t]
     |insTree (t,ts as t'::ts')=
        ランク t < ランク t' の場合 t::ts でなければ insTree(link(t,t'),ts')
  fun insert (x,ts)=insTree(Node(0,x,​​[]),ts)

  fun merge(ts1,[])=ts1
     |merge([],ts2)=ts2
     |マージ (t1::ts1' としての ts1、t2::ts2' としての ts2)=
        ランク t1 < ランク t2 の場合 t1::merge(ts1',ts2)
        そうでなければランク t2 < ランク t1 なら t2::merge(ts1,ts2')
        else mwc(リンク(t1,t2),ts1',ts2')
  (*mwc=キャリーとマージ*)
  および mwc (c,ts1,[])=insTree(c,ts1)
     |mwc (c,[],ts2)=insTree(c,ts2)
     |mwc (c,ts1 as t1::ts1', ts2 as t2::ts2')=
        ランク c < ランク t1 の場合
        ランク c < ランク t2 の場合、 c::merge(ts1,ts2)
                  else mwc(リンク(c,t2),ts1,ts2')
        else mwc(リンク(c,t1),ts1',ts2)
終わり

Okasaki の実装が O(log n) であることの証明: キャリーが「高価」(1 つまたは複数のリンクが必要) である場合、ゼロが生成されます。したがって、次の高価なキャリーは、そのポイントに到達すると停止します。そのため、すべてのキャリーを伝播するために必要なリンクの総数は、伝播前のバイナリ表現の全長程度以下であり、これは ceil(log n) によって上に制限されます。ここで、n はより大きなヒープのサイズです。

4

0 に答える 0