リンクされたリストO(1)の途中に挿入するのはなぜですか?


105

リンクされたリストに関するウィキペディアの記事によると、リンクされたリストの途中に挿入することはO(1)と見なされます。O(n)だと思います。リストの最後近くにある可能性のあるノードを見つける必要はありませんか?

この分析では、ノード操作の発見(必須ではあります)と挿入自体の説明は含まれていませんか?

編集

リンクリストには、配列に比べていくつかの利点があります。リストの特定のポイントへの要素の挿入は一定時間の操作ですが、配列への挿入は要素の半分以上を移動する必要がある場合があります。

上記の文は私に少し誤解を招くものです。私が間違っている場合は私を修正しますが、結論は次のようになります:

配列:

  • 挿入/削除のポイントを見つけるO(1)
  • 挿入/削除の実行O(n)

リンクリスト:

  • 挿入/削除のポイントを見つけるO(n)
  • 挿入/削除の実行O(1)

私はあなたが位置を見つける必要がない唯一の時間はあなたがそれへのある種のポインタを保持している場合だと思います(いくつかのケースでは頭と尾のように)。したがって、リンクリストは常に挿入/削除オプションの配列に勝るとは言えません。

回答:


113

正解です。この記事では、「インデックス作成」を別の操作と見なしています。そのため、挿入自体はO(1)ですが、その中間ノードに到達するのはO(n)です。


3
同じ位置に複数のオブジェクトを挿入すると、大きな違いが生じます...
QUITあり-Anony-Mousse

@ Anony-Mousseもう少し説明してもらえますか?つまり、複数のオブジェクトを挿入するときに、挿入位置を一度だけ見つける必要がありますか?
MyTitle 2013年

2
既存のリストのサイズはO(n)であり、そこで行う予定の挿入数ではありません。
QUITあり-Anony-Mousse 2013年


25

いいえ、挿入することを決定した場合、リストを繰り返し処理している途中であると見なされます。

リンクリストの操作は、実際には一般的な「リスト」としてではなく、ノードのコレクションとして扱われる方法で行われることが多く、ノード自体をメインループのイテレータとして考えることができます。そのため、リストをざっと見ていくと、ビジネスロジックの一部として、新しいノードを追加する(または古いノードを削除する)必要があることに気づき、それを実行します。1回の反復で50個のノードを追加できます。これらのノードはそれぞれ、隣接する2つのノードのリンクを解除して新しいノードを挿入する時間はO(1)です。

編集:男、2番目の段落を入力すると、最初のレスポンダーではなく、突然、5番目に最初の4と同じことを言います。


1
ええ、それはうんざりです...リンクリストの挿入の複雑さは既に目的のポインタにあるというコンテキスト内で考慮されると述べる価値があるので、私はあなたの+1しました。
Daniel Macias

6

新しいノードの後に​​すべてのアイテムを移動する必要がないため、そのグラフが示す配列と比較するために、それはO(1)です。

そのため、はい、彼らはあなたがそのノードへのポインタをすでに持っているか、ポインタを取得するのは簡単だと想定しています。言い換えると、問題は「Xのノードが指定されている場合、このノードの後に​​挿入するコードは何ですか?」挿入点から始めます。


5

リンクリストへの挿入は、リスト全体での繰り返しとは異なります。アイテムを見つけるのではなく、ポインターをリセットしてアイテムをそこに配置します。フロントエンドの近くに挿入されるか、エンドの近くに挿入されるかは関係ありません。挿入には、ポインターの再割り当てが含まれます。もちろん、それがどのように実装されたかによって異なりますが、それがリストの強みです。簡単に挿入できます。インデックスを介したアクセスは、配列が優れている場所です。ただし、リストの場合、通常、n番目の項目を見つけるにはO(n)になります。少なくともそれは私が学校で覚えていることです。


3

それはループを含まないためです。

挿入は次のようなものです:

  • 要素を挿入
  • 前へのリンク
  • 次へリンク
  • できた

いずれにしても、これは一定の時間です。

したがって、n個の要素を次々と挿入することはO(n)です。


3

この分析では、ノード操作の発見(必須ではあります)と挿入自体の説明は含まれていませんか?

了解しました。特定の時点での挿入は、後に挿入するアイテムへのポインタをすでに保持していることを前提としています。

InsertItem(item * newItem, item * afterItem)


2

いいえ、検索は考慮されていません。ただし、リストの中央にあるアイテムへのポインターを既に保持している場合、その時点での挿入はO(1)です。

それを検索する必要がある場合は、検索時間を追加する必要があります。これはO(n)である必要があります。


0

この記事では、配列とリストを比較します。配列とリストの両方の挿入位置を見つけることはO(N)なので、この記事ではそれを無視します。


1
配列の挿入ポイントがO(1)にならないでしょうか?配列は連続したメモリに格納されるため、オフセットを追加するだけで済みます。
Rob Sobers、

@ vg1890-最初にオフセットを見つける必要があります。

0

O(1)は、新しいアイテムを挿入するアイテムがあるという事実に依存しています。(前または後)。そうでない場合は、そのアイテムを見つける必要があるため、O(n)です。


0

これは、O()表記で数えることを選択した場合にすぎないと思います。カウントする通常の操作を挿入する場合は、コピー操作です。配列の場合、途中で挿入すると、その位置より上のすべてがメモリ内にコピーされます。リンクされたリストでは、これは2つのポインタを設定することになります。挿入する場所に関係なく、場所を見つける必要があります。


0

リンクされたリストの操作がO(1)の後に挿入するノードの参照がある場合。
配列の場合、すべての結果のノードを移動する必要があるため、O(n)のままです。


0

最も一般的なケースは、おそらくリストの最初または最後に挿入することです(リストの最後を見つけるのに時間がかからない場合があります)。

配列の最初または最後に項目を挿入する場合とは対照的です(配列の最後にある場合は配列のサイズを変更し、最初にある場合はすべての要素のサイズを変更して移動する必要があります)。


空の要素のバッファーを最後に保持する場合、配列の最後に項目を挿入することでO(1)にすることは可能ですが、挿入は依然としてO(1)になる場合があります。ほとんどのコレクションはこれを行います。要素番号(n + x)%lenを返すようにインデックス演算子を変更することにより、配列の先頭に不活性化するアイテムをO(1)にすることもできます。ここで、xはアイテムを先頭に挿入した回数ですリストの。dequeのは時々このように実装されている(だけでなく、時には二重リンクリストで実装されている。
ブライアン・
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.