web-dev-qa-db-ja.com

配列の代わりにリンクリストを使用するための具体的なルールは何ですか?

リンクされたリストは、要素の安価な挿入と削除が必要な場合、および要素がメモリ内で互いに隣接していないことが問題ではない場合に使用できます。

これは非常に抽象的なものであり、配列ではなくリンクリストを使用する理由を具体的に説明したいと思います。私はプログラミングの経験があまりないので、実際の経験は(もしあれば)あまりありません。

18
rightfold

これは、例と類推の間の一部です。いくつかの用事があるので、一枚の紙をつかんで書きます:

  • バンク
  • 食料品
  • ドライクリーニングを落とす

次に、スタンプも購入する必要があることを覚えています。あなたの町の地理のために、あなたは銀行の後にそれをする必要があります。リスト全体を新しい紙にコピーできます。

  • バンク
  • 切手
  • 食料品
  • ドライクリーニングを落とす

またはあなたが持っていたものに落書きすることができます:

  • 銀行.......スタンプ
  • 食料品
  • ドライクリーニングを落とす

他の用事を考えたように、あなたはそれらをリストの一番下に書くかもしれませんが、矢印はそれらをどの順序で実行するかを思い出させます。これはリンクされたリストです。何かを追加するたびにリスト全体をコピーするよりも速くて簡単です。

次に、銀行にいる間、携帯電話の呼び出し音が鳴ります。 STAMPSをリストから外すだけで、STAMPSが含まれていないまったく新しいものに書き換えることはありません。

これで、実際にエランドリストをコード(おそらく、地理に基づいてエランドを並べ替えるアプリ)に実装でき、リンクリストをコードで実際に使用するのに十分な可能性があります。たくさんのアイテムを追加したり削除したり、注文したりしたいが、挿入や削除のたびにリスト全体を再コピーしたくない。

37
Kate Gregory
  • chaining を使用してハッシュの衝突を解決するハッシュテーブルは、通常、バケット内の要素のバケットごとに1つのリンクリストを持っています。
  • 単純なメモリアロケータは、未使用のメモリ領域の フリーリスト を使用します。基本的には、リストポインタがフリーメモリ自体の中にあるリンクリストです。
  • FATファイルシステム では、大きなファイルのメタデータは、FATエントリのリンクリストとして編成されます。
18

C言語の「コールスタック」は、x-86(およびその他のほとんどの)バイナリAPIでは リンクリストとして実装 です。

つまり、C言語のプロシージャー呼び出しは、先入れ後出しの規則に従います。 (場合によっては再帰的な)関数呼び出しの実行結果は、「呼び出しスタック」、または単に「スタック」と呼ばれることもあります。

CALL x86命令は、「コールスタック」を使用してリンクリストを実装することになります。 CALL命令は、%EIPレジスタの内容、命令のアドレスafterCALLをスタックメモリにプッシュします。呼び出された関数プロローグは、呼び出し関数内のローカル変数の最下位アドレスである%EBPレジスタの内容をスタックメモリにプッシュします。次に、呼び出された関数プロローグは%EBPを現在の関数のスタックベースに設定します。

つまり、%EBPは、呼び出し元関数の%EBP値のアドレスを保持するメモリ位置へのポインタです。これはリンクされたリストにすぎず、CALLを介してハードウェアに部分的に実装されています。

これが良いところまでは、x86 CPUが関数呼び出しを実装する方法です。特に、関数が独自の引数のコピーと関数にローカルな変数を持っている関数呼び出しです。すべての関数呼び出しは、「呼び出しスタック」にいくつかの情報をプッシュします。これにより、CPUは、呼び出し先関数または呼び出し元関数からの干渉を受けることなく、呼び出し元関数で中断された場所を取得できます。

12
Bruce Ediger

リンクされたリストを使用して、メッセージキューを実装できます。

メッセージキューは、後で処理するためにイベントに関する情報を格納する構造です。たとえば、ユーザーがキーを押すか、マウスを動かすと、これがイベントになります。アプリケーションは、イベントが発生した瞬間にビジーになる可能性があるため、イベントが発生した正確な瞬間にイベントを処理することは期待できません。したがって、イベントはメッセージキューに配置され(どのキーが押されたか、またはマウスがどこに移動したかに関する情報)、アプリケーションに余裕があるときに、メッセージキューをチェックし、そこからイベントをフェッチして処理します。それら。 (これはミリ秒の時間枠内で発生するため、目立ちません。)

先ほど説明した使用シナリオから、メッセージキューに格納されているイベントにランダムにアクセスする必要がないことは明らかです。そこにメッセージを保存して取得できることだけが重要です。したがって、最適な挿入/削除時間を提供するリンクリストを使用することは理にかなっています。

(メッセージキューが循環配列リストを使用して実装される可能性が高い、または可能性が高い、またはほぼ可能性があることを指摘するために突入しないでください。これは技術的な詳細であり、制限があります。その中の限られた数のメッセージ。)

3
Mike Nakis