配列とリンクリスト


200

誰かがリンクされたリストを配列で使用したいのはなぜですか?

リンクされたリストをコーディングすることは、間違いなく、配列を使用するよりも少し多くの仕事であり、何が追加の努力を正当化するのか疑問に思うかもしれません。

新しい要素の挿入はリンクされたリストでは取るに足らないことだと思いますが、これは配列の主要な作業です。リンクリストを使用して一連のデータを格納することと、配列に格納することには、他に利点がありますか?

この質問は一般的なデータ構造に関係していますが、他の質問は特定のJavaクラスについて具体的に尋ねているため、この質問この質問の複製ではありません。


1
関連-ArrayList <>でLinkedList <>を使用する場合 -それはJavaですが、配列(ArrayList)とリンクリストはおそらくどの言語でも同じパフォーマンスを発揮します。
Bernhard Barker


1
@rootTraveller実際に私の質問が最初に投稿されたため、その質問はこの質問の複製になります。
Onorio Catenacci

回答:


147
  • リンクリストに異なるサイズのデータ​​を格納する方が簡単です。配列は、すべての要素がまったく同じサイズであることを前提としています。
  • あなたが述べたように、リンクされたリストは有機的に成長する方が簡単です。アレイのサイズは事前に把握しておくか、拡張する必要があるときに再作成する必要があります。
  • リンクされたリストをシャッフルすることは、何が何を指すかを変更することの問題です。配列のシャッフルはより複雑であり、および/またはより多くのメモリを必要とします。
  • イテレーションがすべて「foreach」コンテキストで発生する限り、イテレーションのパフォーマンスが失われることはありません。

19
異なるサイズのアイテムはどのように異なって扱われますか?リンクされたリストは、次のフィールドを持つ固定構造体を使用するか(固定サイズが必要)、または車内のデータへのポインターを格納します(可変サイズOK)。ベクトルを使用すると、どちらのアプローチも同じくらい簡単です。シャッフルについても同じです。
ブライアン、

32
配列のシャッフルはそれほど複雑ではないでしょう。
ヒューアレン

23
この答えは正しくなく、誤解を招くものです。(宣言時に配列のサイズを知る必要がある場合を除きます)
Robert Paulson

35
データの局所性のため、リンクされたリストの反復は遅くなりませんか?
Firas Assaad 2008年

6
@Rick、ベクトルは通常、必要なスペースを全体的に割り当て、サイズが増加するたびに新しいスペースを割り当てる必要がないようにします。その結果、ベクターは通常、メモリの使用量がはるかに少なくなり、リンクリストよりも多くなります。
Winston Ewert、2011

179

もう1つの正当な理由は、リンクされたリストが効率的なマルチスレッド実装に適していることです。これは、変更がローカルで行われる傾向があるためです。データ構造のローカライズされた部分での挿入と削除のポインタは1つまたは2つだけです。したがって、同じリンクリストで多くのスレッドを処理できます。さらに、CASタイプの操作を使用してロックフリーバージョンを作成し、重いロックを完全に回避することができます。

リンクされたリストを使用すると、変更が行われている間にイテレータがリストをトラバースすることもできます。変更が衝突しない楽観的なケースでは、反復子は競合なしで続行できます。

配列の場合、配列のサイズを変更する変更では、配列の大部分をロックする必要がある可能性が高く、実際、これが配列全体のグローバルロックなしで行われるため、変更により世界情勢が停止することはほとんどありません。


9
アレックス-それは私には決して起こらなかっただろう興味深い考察です。とても良い答えです。できれば2回賛成します。:-)
オノリオカテナッチ

5
スキップリスト(特に、Java 6のConcurrentSkipListMap)を参照して、これでどこに行けるかを確認してください。CSLMは、優れたパフォーマンスを持つソートされた並行マップです。同期したTreeMapよりはるかに優れています。 tech.puredanger.com/2007/10/03/skip-lists
Alex Miller、

…ただし、「リスト」が名前のどこかにある場合でも、リストであるConcurrentSkipListMapConcurrentSkipListMap、リストではありません。どちらも、ソートされた一意のキーが必要です。List、つまり任意の順序で重複する要素を許可するデータ構造が必要な場合、これは適切ではなくLinkedList、同時に更新可能なもののようなデータ構造を作成するには、かなりの時間を費やす必要があります。同時キューまたは両端キューのみが必要な場合は、はい、既存の例もありますが、同時List…これが可能であるとは確信していません。
Holger、2018

128

ウィキペディアには違いについて非常に良いセクションがあります。

リンクリストには、配列に比べていくつかの利点があります。要素は無制限にリンクリストに挿入できますが、配列は最終的にいっぱいになるか、サイズを変更する必要があります。これは、メモリが断片化されている場合でも不可能である可能性がある高価な操作です。同様に、多くの要素が削除された配列は、無駄に空になるか、小さくする必要があります。

一方、配列はランダムアクセスを許可しますが、リンクリストは要素への順次アクセスのみを許可します。一重リンクリストは、実際には、一方向にしかトラバースできません。このため、リンクリストは、ヒープソートなど、インデックスで要素をすばやく検索するのに役立つアプリケーションには適していません。参照とデータキャッシュの局所性により、配列へのシーケンシャルアクセスは、多くのマシンのリンクリストよりも高速です。リンクリストは、キャッシュのメリットをほとんど受けません。

リンクリストのもう1つの欠点は、参照に必要な追加のストレージであり、文字やブール値などの小さなデータアイテムのリストでは、実際には参照が実用的ではありません。また、遅くなる可能性があり、単純なアロケータを使用すると、新しい要素ごとにメモリを個別に割り当てるのが無駄になり、問題は一般にメモリプールを使用して解決されます。

http://en.wikipedia.org/wiki/Linked_list


4
これは完璧な答えです。両方の長所と短所を簡潔に説明しています。
リック

ありがとう))とてもシンプルですが、wikiでは見ていません)
Timur Fayzrakhmanov

58

さらに追加します-リストは純粋に機能的なデータ構造として機能できます。

たとえば、同じ終了セクションを共有する完全に異なるリストを持つことができます

a = (1 2 3 4, ....)
b = (4 3 2 1 1 2 3 4 ...)
c = (3 4 ...)

つまり:

b = 4 -> 3 -> 2 -> 1 -> a
c = a.next.next  

およびによってポイントされaているデータをコピーする必要はありません。bc

彼らは不変変数を使用する関数型言語、でとても人気がある理由はここにある- prependtailの操作は、元のデータをコピーすることなく、自由に発生する可能性があります-あなたは不変のようにデータを処理しているときに、非常に重要な機能を。


4
さらに、私が思いつかなかった非常に興味深い考慮事項。ありがとうございました。
Onorio Catenacci

Pythonでこれを行うにはどうすればよいですか?
16年

29

リストの真ん中に挿入する方が簡単です-リンクされたリストの真ん中から削除する方が配列よりもはるかに簡単です。

しかし率直に言って、私はリンクされたリストを使用したことがありません。高速な挿入と削除が必要なときはいつでも、高速な検索も必要だったので、HashSetまたはディクショナリに行きました。


2
ほとんどの場合、挿入と削除はほとんどの時間を検索した後に行われるため、時間の複雑さの合計も考慮する必要があります。
MA Hossain Tonu 2012年

28

2つのリンクリスト(特に2つの二重リンクリスト)のマージは、2つの配列のマージよりもはるかに高速です(マージが破壊的であると仮定した場合)。前者はO(1)をとり、後者はO(n)をとります。

編集:明確にするために、ここでは、マージソートではなく、順序付けされていない意味での「マージ」を意味しました。おそらく「連結」のほうがいい言葉でしょう。


2
1つのリストを他のリストに単に追加する場合のみ。2つのソートされたリストを実際にマージしている場合、O(1)よりもログがかかります。
Herms

3
@Herms、ただし、余分なメモリを割り当てずに、2つのソートされたリンクリストをマージできます。両方のリストをトラバースし、ポインタを適切に設定するだけです。2つの配列をマージするには、通常、少なくとも1つの追加の配列が必要です。
ポールトンブリン

1
はい、リストをマージする方がメモリ効率が良くなりますが、それは私がコメントしていることではありませんでした。リンクされたリストをマージすることはO(1)であると言うことは、ケースの明確化なしでは非常に誤解を招くものです。
Herms

@Hermsマージリストは、賢明なデータモデルで配列をマージするよりもメモリ効率がよくありません。
Alexei Averchenko 2013

2
Alexei Averchenko:O(1)メモリを使用して、2つのリストを連結したり、2つのソート済みリストをマージソートしたりすることもできます。2つの配列を連結するには、配列がメモリ内ですでに隣接している場合を除いて、必ずO(n)メモリが必要です。あなたが目指している点は、n個の要素のリストとn個の要素の配列の両方がO(n)メモリを使用するということですが、リンクリストの方が係数が高くなります。
ラピオン2013

17

ArrayListとLinkedListに対する広く認められていない議論は、デバッグ中のLinkedListsが不快であることです。バグ、増加など、プログラムを理解するためにメンテナンス開発者が費やす時間は増加し、IMHOは、エンタープライズアプリケーションでのパフォーマンス向上のナノ秒やメモリ消費のバイトを正当化しない場合があります。時々(まあ、もちろんそれはアプリケーションのタイプに依存します)、数バイトを浪費する方が良いですが、より保守しやすい、または理解しやすいアプリケーションを持っています。

たとえば、Java環境でEclipseデバッガーを使用して、ArrayListをデバッグすると、非常に理解しやすい構造が明らかになります。

arrayList   ArrayList<String>
  elementData   Object[]
    [0] Object  "Foo"
    [1] Object  "Foo"
    [2] Object  "Foo"
    [3] Object  "Foo"
    [4] Object  "Foo"
    ...

一方、LinkedListのコンテンツを監視し、特定のオブジェクトを見つけることは、LinkedListの内部をフィルターで除外するために必要な認識オーバーヘッドは言うまでもなく、ツリーの展開という悪夢になります。

linkedList  LinkedList<String>
    header  LinkedList$Entry<E>
        element E
        next    LinkedList$Entry<E>
            element E   "Foo"
            next    LinkedList$Entry<E>
                element E   "Foo"
                next    LinkedList$Entry<E>
                    element E   "Foo"
                    next    LinkedList$Entry<E>
                    previous    LinkedList$Entry<E>
                    ...
                previous    LinkedList$Entry<E>
            previous    LinkedList$Entry<E>
        previous    LinkedList$Entry<E>

17

まず第一に、C ++のリンクリストでは、配列よりも操作するのにそれほど問題はないはずです。リンクされたリストにはstd :: listまたはboostポインタリストを使用できます。リンクリストと配列の主な問題は、ポインターとひどいランダムアクセスに必要な余分なスペースです。あなたがリンクされたリストを使用する必要があります

  • データにランダムにアクセスする必要はありません
  • 特にリストの中央にある要素を追加/削除します

14

私にとってはこうです

  1. アクセス

    • リンクリストは、要素への順次アクセスのみを許可します。したがって、アルゴリズムの複雑さはO(n)の次数です。
    • 配列はその要素へのランダムアクセスを許可するため、複雑さはO(1)の次数です。
  2. ストレージ

    • リンクされたリストには、参照用の追加のストレージが必要です。そのため、文字やブール値などの小さなデータ項目のリストでは実用的ではありません。
    • 配列は、次のデータ項目を指すために追加のストレージを必要としません。各要素にはインデックスを介してアクセスできます。
  3. サイズ

    • リンクリストのサイズは本質的に動的です。
    • 配列のサイズは宣言に制限されています。
  4. 挿入/削除

    • 要素はリンクリストに無期限に挿入および削除できます。
    • 配列への値の挿入/削除は非常にコストがかかります。メモリの再割り当てが必要です。

あなたは2番号2、及び2番号3 :)持っている
ヘンゲーム

空の配列を宣言して、必要に応じてデータを追加し続けることができます。それでもどのようにして固定サイズになりますか?
HebleV 2017

11

2つのこと:

リンクされたリストをコード化することは、間違いなく、配列を使用するよりも少し手間がかかります。

C ++を使用する場合は、リンクリストをコーディングしないでください。STLを使用するだけです。ほとんどがすでに実装されているため、実装がどれほど難しいかが、あるデータ構造を別のデータ構造よりも選択する理由になることはありません。

配列とリンクリストの実際の違いについては、構造体をどのように使用するかは、私にとって最も重要です。ベクトルという用語は、C ++でサイズ変更可能な配列の用語であるため使用します。

リンクされたリストへのインデックス付けは、与えられたインデックスに到達するためにリストをトラバースする必要があるために遅くなりますが、ベクトルはメモリ内で隣接しており、ポインター演算を使用してそこに到達できます。

リンクされたリストの最後または最初に追加するのは簡単です。1つのリンクを更新するだけでよく、ベクターでは、サイズを変更して内容をコピーする必要がある場合があります。

アイテムをリストから削除するのは簡単です。リンクのペアを解除してから、それらを元に戻す必要があるだけです。ベクトルからのアイテムの削除は、順序を気にするかどうかに応じて、速くなったり遅くなったりします。削除したいアイテムの上に最後のアイテムを入れ替える方が速いですが、下に移動した後のすべてのシフトは遅くなりますが、順序は保持されます。


上で誰かに言ったように、私は質問が私に与えられた方法を関係づけようとしていました。とにかく、C ++で配列(または自分がリンクしたロールリスト)を使用することは決してありません。両方のSTLバージョンを使用します。
Onorio Catenacci

10

Eric Lippertは最近、配列を保守的に使用する必要がある理由の1つについて投稿しました。


2
確かに良い投稿ですが、リンクされたリストと配列の議論では関係ありません。
ロバートポールソン、

2
配列の短所とリストの利点の両方について説明しているため、リストの実装に関係なく、Ericの記事の多くは関連性があると思います。
Bevan

8

高速な挿入と削除は、リンクされたリストにとって確かに最良の議論です。構造が動的に拡大し、任意の要素(動的スタックやキューなど)への一定時間のアクセスが不要な場合は、リンクリストが適しています。


7

ここに簡単なものがあります:アイテムの削除はより速いです。


7

リンクリストは、コレクションが絶えず成長および縮小している場合に特に役立ちます。たとえば、配列を使用してキューを実装しようとする(最後に追加し、前面から削除する)ことを想像するのは困難です。一方、リンクリストを使用するのは簡単です。


4
あまりにも多くの作業をせずに、配列ベースのキューを作成することもできますが、それでもまだ高速で効率的でした。どのインデックスが「ヘッド」で、どのインデックスが「テール」であるかを追跡する必要があるだけです。これは、固定サイズのキュー(たとえば、カーネルのキーボードバッファー)が必要な場合は、かなりうまく機能します。
Herms

3
また、お気に入りのアルゴリズム参照で調べたい場合は、「循環バッファー」と呼ばれます。
スティーブジェソップ

7

リストの中央から追加したり削除したりする以外に、リンクリストは動的に拡大および縮小できるので、リンクリストの方が好きです。


6
ベクトル(=基本的に配列)もそれが可能であり、参照の局所性の問題により、ベクトルの償却コストは通常​​、リストのコストよりも低くなります。
Konrad Rudolph、

7

自分のリンクリストをコーディングする人はもういません。それはばかげているでしょう。リンクされたリストを使用すると、より多くのコードが必要になるという前提は、間違っています。

最近では、リンクされたリストを作成することは、学生が概念を理解できるようにするための練習にすぎません。代わりに、全員が事前に作成されたリストを使用します。C ++では、質問の説明に基づいて、おそらくstlベクトル(#include <vector>)を意味します。

したがって、配列対リンクリストを選択することがあり、完全にあなたのアプリケーションのニーズに対する各構造の異なる特性を計量について。追加のプログラミングの負担を克服しても、決定に影響はありません。


2
Er..umm .. std :: vectorはリンクリストではなく配列です。標準のリンクリストは、まあ、std :: listです。
James Curran、

1
ええ、でも、ベクターは、オペレーションが求めているもの、つまり動的配列の置き換えに近いと思います。
Joel Coehoorn、2008年

@ジョエル、私はC ++を学ぼうとしているこのフェローから私に与えられた質問を関連づけようとしていました。私は自分のリンクリストをコーディングすることも気にしませんが、それが彼が私に尋ねた方法です。:-)
オノリオカテナッチ

カスタムコンパイラーが存在するメモリ制約のある環境(マイクロコントローラー)では、すべての言語(C ++のコンテナーなど)が実装されているわけではありません。したがって、独自のリンクリストをコーディングする必要がある場合があります。 nongnu.org/avr-libc/user-manual/FAQ.html#faq_cplusplus
Minh Tran

6

それは実際には効率の問題であり、リンクされたリスト内の要素を挿入、削除、または移動する(単純にスワップではない)オーバーヘッドは最小限です。つまり、操作自体はO(1)で、配列のO(n)です。データのリストを頻繁に操作している場合、これは大きな違いを生む可能性があります。データ型の操作方法に基づいてデータ型を選択し、使用しているアルゴリズムに最も効率的なものを選択します。


6

配列は、アイテムの正確な数がわかっている場合、およびインデックスによる検索が意味がある場合に意味があります。たとえば、特定の瞬間のビデオ出力の正確な状態を圧縮せずに保存したい場合は、おそらくサイズ[1024] [768]の配列を使用します。これは私に必要なものを正確に提供し、リストは与えられたピクセルの値を取得するのにはるかに遅くなります。配列が意味をなさない場所では、データを効果的に処理するために、一般にリストよりも優れたデータ型があります。


6

配列とリンクリスト:

  1. 断片化されたメモリが原因で、配列メモリの割り当てが失敗することがあります。
  2. 配列では、すべての要素に連続したメモリ空間が割り当てられるため、キャッシュの方が適しています。
  3. コーディングは配列よりも複雑です。
  4. 配列とは異なり、リンクリストにサイズ制限はありません
  5. リンクリストでは挿入/削除が高速になり、配列ではアクセスが高速になります。
  6. リンクされたリストは、マルチスレッドの観点から見た方が優れています。

-1:これらすべてを列挙するだけでなく、実証する必要があります。
John Saunders、

各ポイントは、上記の回答ですでに説明されています。後発者であるため、列挙する以外に選択肢はありませんでした。ところで、どちらを説明したいですか?
AKS

彼らがすでに説明されているなら、なぜあなたは答えているのですか?
John Saunders、

2
これにより、ディスカッションの概要がわかります。そして、私はそのようなタイプの答えが好きなので、同じ説明を何度も読む必要がありません。そして、私と同じ考え方の人のためにやった。異なるpplには異なるスタイルがあります。新しいものはありません。
AKS

3

配列は本質的に静的なので、メモリ割り当てなどのすべての操作はコンパイル時にのみ発生します。したがって、プロセッサは実行時に少ない労力を費やす必要があります。


3

順序付けされたセットがあるとします。これも、要素を追加および削除して変更します。さらに、後で前の要素または次の要素を取得できるように、要素への参照を保持する機能が必要です。たとえば、本のTo Doリストや段落のセットなどです。

最初に、セット自体の外にあるオブジェクトへの参照を保持したい場合は、オブジェクト自体を格納するのではなく、配列にポインタを格納することになります。そうしないと、配列に挿入できなくなります。オブジェクトが配列に埋め込まれている場合、オブジェクトは挿入中に移動し、それらへのポインターはすべて無効になります。配列インデックスについても同様です。

あなたが最初に気づいたように、最初の問題は挿入です-リンクされたリストはO(1)への挿入を許可しますが、配列は通常O(n)を必要とします。この問題は部分的に克服できます。読み取りと書き込みの両方が最悪の場合は対数である配列のような序数アクセスインターフェイスを提供するデータ構造を作成することが可能です。

2番目の、より深刻な問題は、次の要素を見つける要素がO(n)であることです。セットが変更されていない場合は、ポインタの代わりに要素のインデックスを参照として保持して、find-nextをO(1)操作にすることができますが、オブジェクト自体へのポインタしかありません。 「配列」全体をスキャンする以外の方法で、配列内の現在のインデックスを特定します。これは、配列にとって乗り越えられない問題です。挿入を最適化できたとしても、次を検索するタイプの操作を最適化する方法はありません。


これについて詳しく説明していただけますか:「読み取りと書き込みの両方が最悪の場合は対数である配列のような序数アクセスインターフェイスを提供するデータ構造を作成することは可能です。」
ヘンガメ2015

1
WikipediaのDynamic Array / Vriantsセクションにいくつかの情報があります。それは私が念頭に置いていたものではありません...しかし、ページはあるがキーはないb + treeのような構造を想像してください。代わりに、各中間ページは各サブページにある要素の数を記憶し、リーフページは小さな配列の要素。要素をリーフページに挿入するときは、ページの半分を移動してスペースを空けてから、上に移動してすべての祖先ページのアイテム数を更新する必要があります。要素
#Nを検索

3

配列には、O(1)時間で任意の要素にアクセスする特権があります。そのため、バイナリ検索クイックソートなどの操作に適しています。一方、リンクリストは、O(1)時間と同様に挿入削除に適しています。どちらにも長所と短所があり、実装したいものに合わせてどちらか一方を優先します。

-より大きな問題は、両方のハイブリッドを利用できるかどうかです。pythonやperlがリストとして実装するようなもの。


3

リンクリスト

挿入に関してはより好ましい!基本的に何をするかというと、それはポインタを扱うということです

1-> 3-> 4

挿入(2)

1 ........ 3 ...... 4
..... 2

最後に

1-> 2-> 3-> 4

3の2点からの1つの矢印と2の1点の矢印

シンプル!

しかし配列から

| 1 | 3 | 4 |

挿入(2)| 1 | 3 | | 4 | | 1 | | 3 | 4 | | 1 | 2 | 3 | 4 |

まあ誰でも違いを視覚化できます!ちょうど4つのインデックスのために、私たちは3つのステップを実行しています

配列の長さが100万の場合はどうなりますか?配列は効率的ですか?答えはいいえだ!:)

削除についても同じことが言えます!リンクリストでは、ポインタを使用して要素を無効化し、次にオブジェクトクラスを無効化できます。しかし、配列の場合、shiftLeft()を実行する必要があります

お役に立てば幸いです。:)


3

リンクリストは、アレイよりも維持するオーバーヘッドが多く、また、これらすべての点が合意された追加のメモリストレージが必要です。しかし、配列ができないことはいくつかあります。多くの場合、10 ^ 9の長さの配列が必要だとすると、1つの連続したメモリ位置を取得する必要があるため、取得できません。リンクされたリストはここで救世主になる可能性があります。

データを含む複数のものを格納したい場合、それらはリンクリストで簡単に拡張できます。

STLコンテナは通常、リンクされたリストの実装を舞台裏で持っています。


3

1-リンクリストは動的データ構造であるため、メモリを割り当てたり割り当て解除したりすることで、実行時に拡大および縮小できます。そのため、リンクリストの初期サイズを指定する必要はありません。ノードの挿入と削除は本当に簡単です。

2-リンクされたリストのサイズは実行時に増減できるため、メモリの浪費はありません。配列の場合、サイズ10の配列を宣言して6つの要素のみを格納する場合と同様に、4つの要素のスペースが無駄になるなど、大量のメモリが消費されます。メモリは必要な場合にのみ割り当てられるため、リンクリストにはそのような問題はありません。

3-スタックやキューなどのデータ構造は、リンクリストを使用して簡単に実装できます。


2

リンクリストを使用する唯一の理由は、要素の挿入が簡単(削除も)であることです。

不利な点は、ポインターが多くのスペースを取ることです。

そして、そのコーディングについてはより困難です:通常、コードリンクリストは必要ありません(または1回だけ)。それらはSTLに含まれて おり、それを行う必要がある場合でもそれほど複雑ではありません。


2
ポインタは多くのスペースを必要としますか?あんまり。ブール値のリンクされたリストを格納している場合、確かに、パーセンテージでは、ポインターは多くのスペースをとります。しかし、複雑なオブジェクトを格納している場合(これは一般的なケースです)、ポインターはおそらく無視できます。
Herms、

笑顔を忘れてしまった:)しかし、「できる」ではない、と言った。
user15453 2008年

1

また、リンクリストは配列よりも優れていると思います。リンクリストではトラバースしますが、配列ではトラバースしません。


1

言語によっては、これらの欠点と利点のいくつかを考慮することができます。

Cプログラミング言語:リンクされたリストを使用する場合(通常は構造体ポインタを使用)、メモリがリークしていないことを確認する必要があります。先に述べたように、リンクリストは、すべてがポインターを変更するだけなので、簡単にシャッフルできますが、すべてを解放することを忘れないでください。

Java:Javaは自動ガベージコレクションを備えているため、メモリのリークは問題になりませんが、リンクリストの実装の詳細は、高レベルのプログラマーから隠されています。リストの中央からノードを削除するなどの方法は、言語の一部のユーザーが想定するよりも手順が複雑です。


1

なぜ配列にリンクされたリストがあるのですか?一部の人がすでに述べたように、挿入と削除の速度が向上しました。

しかし、多分私たちはどちらか一方の限界で生きる必要はなく、同時に両方の長所を手に入れる必要はありません...え?

配列の削除の場合、「削除済み」バイトを使用して、行が削除されたことを表すことができるため、配列を再編成する必要がなくなりました。挿入や急速に変化するデータの負担を軽減するには、リンクされたリストを使用します。次に、それらを参照するときは、最初にロジックを検索し、次にもう一方を検索するようにします。したがって、それらを組み合わせて使用​​すると、両方の利点が得られます。

本当に大きな配列がある場合は、それを別のはるかに小さい配列またはリンクされたリストと組み合わせて、小さい方の配列が最近使用した20、50、100個のアイテムを保持するようにすることができます。必要なものが短いリンクリストまたは配列にない場合は、大きな配列に移動します。そこで見つかった場合は、「最近使用されたものが再利用される可能性が最も高い」という前提で、小さなリンクされたリスト/配列にそれを追加できます(そうです、リストから最も最近使用されていないアイテムをバンプする可能性があります)。これは多くの場合に当てはまり、.ASPセキュリティアクセス許可チェックモジュールで、簡単、優雅、そして印象的なスピードで取り組む必要があった問題を解決しました。


1

あなたの多くはリンクリストと配列の主要なadv./disに触れてきましたが、ほとんどの比較は一方が他方よりも優れている/悪いということです。配列ではランダムアクセスを実行できますが、リンクリストなどでは不可能です。ただし、これはリンクリストと配列が同様のアプリケーションに適用されることを想定しています。ただし、正しい答えは、特定のアプリケーション展開でリンクリストがアレイよりも優先されること、およびその逆がどのようになるかです。辞書アプリケーションを実装するとしたら、何を使用しますか?配列:mmmバイナリ検索やその他の検索アルゴリズムを使用して簡単に取得できますが、リンクリストの方が優れていると思います。辞書で「Blob」を検索するとします。A-> B-> C-> D ---->のリンクリストがあるのは理にかなっていますか

A -> B -> C -> ...Z
|    |    |
|    |    [Cat, Cave]
|    [Banana, Blob]
[Adam, Apple]

さて、上記のアプローチはより良いのでしょうか、それとも[Adam、Apple、Banana、Blob、Cat、Cave]のフラットな配列なのでしょうか?配列でも可能でしょうか?したがって、リンクリストの主な利点は、次の要素を指すだけでなく、他のリンクリスト/配列/ヒープ/その他のメモリ位置を指す要素を持つことができることです。配列は、格納しようとしている要素のブロックサイズにスライスされた1つのフラットな連続メモリです。一方、リンクリストは、非連続メモリユニット(任意のサイズで何でも格納できます)のチャンクであり、それぞれを指します。他のあなたが望む方法。同様に、USBドライブを作成しているとしましょう。ここで、ファイルを配列またはリンクリストとして保存しますか?私はあなたが私が指しているものを理解していると思います:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.