web-dev-qa-db-ja.com

リンクリストとベクター

過去数日間、私はソフトウェア開発の仕事のための私の最初の電話インタビューの準備をしてきました。質問を調査する中で、私は この記事 を思いつきました。

この一節にたどり着くまで、すべてが素晴らしかったです。

「リンクリストとベクターのどちらを使用しますか?」

現在、経験と研究から、これらは2つの非常に異なるデータ構造です。リンクされたリストは動的配列であり、ベクトルは空間の2Dポイントです。 2つの間に見られる唯一の相関関係は、ベクトルをリンクリストとして使用する場合、たとえばmyVector(my value, pointer to neighbor)

考え?

18
Ryan

Vectorは、 動的配列 の別名です。 C++の動的配列データ構造 に使用される名前です。 Javaの経験がある場合は、ArrayListという名前でそれらを知っているかもしれません。Javaには、ベクターと呼ばれる古いコレクションクラスがあります。設計された。)

ベクトルは、ランダムな読み取りアクセスと後ろへの挿入と削除には適していますが(償却された一定の時間を要します)、前または他の位置への挿入と削除には適していません(アイテムを移動する必要があるため、線形時間)通常、ベクトルはメモリ内で連続して配置されます。そのため、CPUメモリキャッシュが効果的に使用されるため、ベクトルの走査は効率的です。

リンクリスト 一方で、前または後ろ(一定の時間)にアイテムを挿入および削除するのには適していますが、他の多くには特に適していません:たとえば、中央の任意のインデックスでアイテムを削除する最初にノードを見つける必要があるため、リストの時間は直線的です。一方、特定のノードが見つかったら、一定の時間でそのノードを削除したり、新しいアイテムを挿入したりできますが、これはベクターではできません。リンクリストも実装が非常に簡単であるため、一般的なデータ構造になります。

43
Joni

この質問者には少し遅れていることは知っていますが、これは最新のハードウェアでリンクリストを避けるべき理由についてBjarne Stroustrup(C++の発明者)からの非常に洞察力に富んだビデオです。 https://www.youtube.com/watch?v=YQs6IC-vgmo 今日のコンピューターでの高速メモリ割り当てにより、更新されたアイテムでベクターのコピーを作成する方がはるかに迅速です。

5

私はここで一番の答えが好きではないので、MicrosoftのHerb Sutterが実施したこれに関するいくつかの実際の研究を共有すると思いました。テストの結果は、コンテナに最大10万個のアイテムが含まれていましたが、50万個のエンティティでもリンクリストを実行し続けると主張しました。コンテナにミリオンのエンティティを計画する場合を除き、動的コンテナのデフォルトコンテナshouldvector。私は彼が言うことを多かれ少なかれ要約しましたが、下部の参照もリンクします:

「[場合でも]リンクリスト内のノードを事前に割り当てると、半分のパフォーマンスが得られますが、それでも(ベクターよりも)劣ります。なぜですか?まず、スペースが増えます-要素ごとのオーバーヘッド(理由)-リンクされたリストに含まれる前方および後方ポインター-さらに(そしてもっと重要なことですが)アクセス順序リンクされたリストは挿入ポイントを見つけるために横断しなければなりません。ベクトルが実行していたことですが、実際に発生しているのは、プリフェッチャーが高速であることです。メモリ内で効率的にマッピングされたデータを使用して線形トラバーサルを実行しますたとえば、定義されて配置されたポインターのベクトルを使用すると)、ほぼすべてのシナリオでリンクリストよりも優れています。」

https://youtu.be/TJHgp1ugKGM?t=2948

2
simon

現在の要素の位置を保持するポインターと、リスト内を移動するために使用されるメソッドがある場合(.moveToStart()など) 、.moveToEnd().next()など)、一定の時間で削除および挿入できます。

1
blackbox66