配列に似た不変の(永続的な)データ構造の実装で、高速なインデックス付け、追加、追加、繰り返し


11

配列に似た永続的なデータ構造(ただし不変)を探しています。これにより、高速なインデックス作成、追加、先頭付加、反復(適切な局所性)操作が可能になります。

Clojureは永続的なVectorを提供しますが、これは高速追加専用です。ScalaのVectorは効果的に一定時間の追加と付加を行いますが、Clojureベクトルと同じデータ構造(ビットマップベクトルトライ)に基づいているため、実装方法を取得できません。いくつかのトリックがないと、高速なプリペンドはできません。

すぐに使用できる実装ではなく、そのようなデータ構造を自分で実装する方法の説明に興味があります。

回答:


13

明白な候補は、永続的なバランスのとれたバイナリツリーです。リストしたすべての操作は、パスコピーを使用して、またはO lg n 時間で実行できます。このランタイムを実現する方法の詳細については、以下で参照されているChris Okasakiの本または私の回答はこちらを参照してくださいO(1)O(lgn)

もちろん、変形として、そのようなツリーの各リーフ自体が不変の配列(連続した値のシーケンス)を含むことができます。これにより、値の更新の効率が低下しますが、既存の値を変更するつもりがない場合は、追加して追加するだけで、状況によってはうまく機能する場合があります。このようにして、ベクトルは不変のシーケンスのシーケンスとして表され、葉に不変の配列を持つ平衡バイナリツリーとして表されます。これにより、高速なインデックス作成(葉の数の対数)、高速な追加と付加、高速な反復が可能になります。最悪の場合の漸近的な複雑さはこれより良くはありませんが、実際のパフォーマンスは大幅に向上する可能性があります。

標準的なリファレンスは、Chris Okasakiの1998年の著書「純粋に機能的なデータ構造」です。
こちらもご覧ください


ありがとうございました。RRBツリーは適切な候補のようであり、すでに(完全ではない)Clojure実装があります。
Tvaroh 2014年

岡崎は不変性と永続性の下でこれらのランタイムを達成する方法を教えてくれると思いますか?
ラファエル

1
@ラファエル、うん。ランタイムを実現する方法を説明するための参照を追加しました(私の回答の冒頭に)。
DW

4

このようなデータ構造の1つの実装について、正規表現の増分一致に関する記事で説明しました-http://jkff.info/articles/ire/#ropes-strings-with-fast-concatenationとそのセクションの前後のテキストを参照してください。

これは、さまざまな高さの一定のツリーです(Bツリーや2-3ツリーなど)。基本的には要素ごとのオーバーヘッドを回避するために、葉が(N、2N-1)配列である(2,3)ツリーです。((N、2N-1)配列は、長さがN..2N-1の範囲の配列です。)Nを大きくするとオーバーヘッドが小さくなりますが、分割と連結の複雑さが直線的に増加します。インデックス付け、分割、連結などの操作は、2〜3のツリーでの動作と非常に似ており、リーフレベルで一般化すると(N、2N-1)になります。


リンクが切れます。適切で強固な参照を提供してください(リンクがなくても論文を見つけてもらいやすくなります)。
ラファエル

私は自分の個人的なウェブサイトでのみ、どのジャーナルにも論文を発表しませんでした。おそらくArxivに置くべきでしょう、良い考えです。
jkff 2014年

私は主に著者、タイトル、年について考えていました-必要に応じてグーグルを簡単にします。それをarXivに置くと、さらに良いでしょう、本当です!
ラファエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.