スキップリストはどのように機能しますか?


14

宿題の割り当てでは、スキップリストの仕組みを理解する必要があります。

私はもう2年以上プログラミングをしています(実際にはそれほど長くないことを知っています)。スキップリストを聞いたことがありません。

私が見つけることができるすべてのガイドを見てきましたが、それらがどのように機能するのかまだほとんど理解していません。実装例をコードレビューで検索しても、レビューは1つしか見つかりませんでした。そして、それは完全な実装でさえありません。コースが提供するサンプル実装を確認しましたが、それは絶対にひどいものです。適切なメソッドの欠如と1文字の変数名の間で、どのように機能するのか見当がつきません。

スキップリストはどのように機能しますか?より高度なデータ構造を理解するにはスキップリストの知識が必要ですか?



1
教育アドバイスは、明らかにトピック外です。これは教育ではなくデータ構造に関するものであるため、これらの部分を削除するように質問を編集しました。編集したウィキペディアのリンクを読んで、あなたがまだ理解していないことに関するより具体的な詳細で質問を更新することもお勧めします。

@スノーマンありがとう。「先生に尋ねる」などのコメントを防ぐためだけに追加しました。次回もそのことを心に留めておきます。そして、質問を変更する編集を追加しました。最後に、私は人々が彼らがどのように機能するかを説明するように求めていません。彼らが学ぶことの重要性を知りたいだけです。
発癌性

1
@Carcigenicateがそれらがどのように機能するかを説明することは、実際にあなたが現実の世界でそれらを見るかどうかを尋ねるというよりも、実際はトピックに関するものです。私たちはあなたが何をしているのか、さまざまな領域だけを推測することができます。現実の世界でそれらを見るかどうかを尋ねることは、「うん、私はそれらを見て、それらを使用する」または「いや、聞いたことがない」-私たちにポーリングします。

回答:


29

昔は、データ構造のクラスで、AVLツリーの仕組みを学びました。私はクラスの1つでそれを持っていたでしょうが、インストラクターは「実際にこれを使用することは決してないだろう」と言い、代わりに2〜3本の木とb *木を代わりに学習させました。これらは、メモリが不足し、プロセスが単独でスレッド化されていた日でした。単一リンクリストが同様に機能する場合は、両端キューは使用しませんでした。

現在、スキップリストはより一般的であり、利用可能なメモリと同時実行性が問題になっています(スキップリストでライターとして動作する場合、AVLツリーのすべてと比較して、あまりロックする必要はありません)。

率直に言って、現在の私のお気に入りのデータ構造は、その下でどのように機能し、どこで使用するのが有利か不利かを簡単に推論できるものです。

あなたは最初から書く必要はありません(インタビューの質問としてそれを取得しない限り-しかし、あなたはAVLツリーを実装する可能性があります)。

あなたはされ、選択したい理由を理解するために必要に行くConcurrentSkipListMapのではなく、JavaでのHashMapか、TreeMapあるいは他のマップの実装のいずれか。


仕組みを理解するには、バイナリツリーの仕組みを理解する必要があります。待って、それを修正させてください。平衡二分木がどのように機能するかを理解する必要があります。バイナリツリーのバランスをとらないと、ルックアップで実際の利点が得られません。

このツリーがあるとしましょう:

二分木

そして、「8」を挿入します。今、私たちは持っています:

不均衡な二分木

そして、それはバランスが取れていません。だから、私たちはいくつかの実装を介してバランスをとる魔法を行っています...

バランスの取れた木

そして、あなたは再びバランスの取れた木を手に入れました。しかし、それは私が手を振った多くの魔法でした。

スキップリストを見てみましょう。

理想的なスキップリスト

これはたまたま理想化されたものです。ほとんどありませんが、スキップリストの理想が近似するバランスの取れたバイナリツリーの性質を示しています。

次に、そこに6を挿入します。これは、リンクリストのように挿入されます。ただし、上から始めて下に行きます。上位は5を指しています。6> 5ですか?はい。さて、トップは最後を指していますので、スタックを下っていきます(5番です)。次は7です。6> 7ですか?いや。したがって、レベルを下げて基本レベルにいるので、5の右側に6を挿入します。

私たちはコインを投げます-私たちが作る頭、私たちが残る尾。しっぽ。これ以上何もする必要はありません。

挿入後にリストをスキップ

その8を今挿入しましょう。8> 5?うん。8> 7?うん。そして今、私たちは矢印とスタックをたどり、8> 11をテストした後、再び最下層にいますか?いや。したがって、7の右側に8を挿入します。

私たちはコインを投げます-私たちが作る頭、私たちが残る尾。しっぽ。これ以上何もする必要はありません。

別の挿入後にリストをスキップ

バランスの取れたツリーでは、ツリーが現在バランスが取れていないことについてすべての作業が行われます。しかし、これはツリーではありません-そのスキップリストです。バランスのとれたツリーを近似します。

ここで、10を挿入します。すべての比較を避けます。

私たちはコインを投げます-私たちが作る頭、私たちが残る尾。ヘッズ!そして再びそれをひっくり返して、再びヘッズ!もう一度裏返します、OK、尾があります。ベースリンクリストの2レベル上。

さらに別の挿入後にリストをスキップ

ここでの利点は、12を挿入する場合、他のすべての比較を行わずに5から10までスキップできることです。スキップリストでそれらをスキップできます。そして、バランスのとれたツリーについて心配する必要はありません。スタッキングの確率的性質がそれを私たちにもたらします。

なぜこれが便利なのですか?10を挿入するとき、構造全体ではなく、5および7と8のポインターで書き込みをロックすることでそれができるからです。そして、私がそれをしている間、読者は一貫性のない状態にならずにスキップリストを通過することができます。同時使用の場合、ロックする必要がないので高速です。最下層での反復処理は、ツリーよりも高速です(ツリーナビゲーション用のBFSおよびDFSアルゴリズムの楽しさ-それらについて心配する必要はありません)。

それに遭遇しますか?あなたはおそらくそれを場所で使用しているのを見るでしょう。著者が選んだ理由と、あなたは知っているよというのではなく、実装のTreeMapか、HashMap構造のため。

これらの多くは私のブログ投稿「The Skip List」から借用しています


ありがとうございました。私が理解できないのは、一般的な実装ですらありません。BSTに似ています。私はそれをどのように実装するかを考えてみましたが、すべてのポインター/参照を管理するという考えは常に私を混乱させました。欲求不満になりすぎたのかもしれません。ありがとう。明日、答えを出発点として取り上げてみます。
発がん性物質

2
@Carcigenicateには、それらを紹介する元の論文-Skip Lists:A Probabilistic Alternative to Balanced Treesも役立つかもしれません。それは、人々の頭をはるかに超えることができるほとんどの学術論文と比較して、かなり理解しやすい論文です。表2に、これらが使用されている理由を示します。挿入または削除のその時間要因は、他のソリューションの複雑さを追加します。

2
リンクリストは「縮退した非常に不均衡なツリー」です。スキップリストは、リストの上にある種のツリー構造を部分的に追加し直すようなものです。個人的に、私は永続的なデータ構造の大ファンであり、その特定のコンテキストでツリーを推論するのは簡単だと思われます。Clojure、Scalaなどが偶然だとは思いません。基本的なデータ構造として、ある種のバグウェルスタイルのハッシュ試行に収束しているようです。(Phil Bagwellは、Scala 2.8のScalaのコレクションフレームワークの再設計にも関与していました。)ただし、スキップリストは依然として優れています。
ヨルグWミッターグ

それは私が今まで読んだスキップリストがどのように機能するかについての最良の説明です。
貪欲な
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.