web-dev-qa-db-ja.com

動的配列の最後にあるアイテムの削除O(n)時間の複雑さ)

私は現在教科書を読んでいて、動的配列が最後に項目を削除するのにO(n)時間を必要とする理由を完全に混乱させています。他のインデックスから項目を削除するとO(n)すべてのデータをコピーし、ギャップを埋めるためにそれらを移動する必要がありますが、最後にある場合は、単にカウントをデクリメントし、インデックスを0またはnullのようなものですか?私は自分の本から写真を含めました。これは、インデックス作成がO(1)であると言う奇妙な原因です。リンクリストのような配列。enter image description here

10
Belphegor

最初に、「動的配列」で本の意味を調べてみましょう。

動的配列(growable arrayresizable arraydynamic tableとも呼ばれます) 、またはarray list)は、要素の追加または削除を可能にするランダムアクセスの可変サイズリストデータ構造です。 [...]
注:スタック、キュー、およびハッシュの章でdynamic arrayの実装を確認します。

このことから、本の著者が定義しているように、配列リストは「動的配列」の例であることがわかります。

しかし、さらに詳しく見ると、この本は次のように述べています。

その配列がいっぱいになるとすぐに、元の配列の2倍のサイズの新しい配列を作成します。同様に、配列内の要素が半分未満の場合、配列サイズを半分に縮小します

(強調は私によって追加されました)

A Java ArrayListはこれを行いません-要素が削除されてもストレージは減少しません。しかし、著者は話している(またはArrayListは)配列サイズを縮小するその場合、最悪の場合、複雑さはO(n)であると言えます。サイズを縮小するには、縮小した配列にn要素をコピーする必要があるからです。

結論:

Java ArrayListの実装には当てはまりませんが、この本の著者が必要に応じて削除時に「配列サイズを小さくする」「動的配列」について話すとき、then配列の最後での削除の最悪の複雑さは、確かにO(n)です。

15
Erwin Bolwidt

そのエントリは、どちらかのようです

  1. 間違っている、または
  2. 本当だが誤解を招く。

動的配列の最終位置にあるオブジェクトを破棄し、サイズをデクリメントして最後の要素を削除することができるのは絶対に正しいことです。動的配列の多くの実装では、サイズ変更操作を実行して、割り当てられた配列のサイズが要素数の一定の要因内にあることを確認する必要がある場合があります。その場合は、はい、新しい配列を作成し、古い要素をコピーして、前の配列を解放する必要があります。これには時間がかかりますO(n)。ただし、これらのサイズ変更は非常にまれであるため、最後から削除を実行するaverageコストはO(1)であることがわかります。 (より技術的な意味では、amortized端から要素を削除するコストはO(1)であると言います)。つまり、個々の操作のコストではなく、一連の操作を実行するための総コストのみを考慮する限り、O(1)の時間ごとに各操作のコストを装うことは間違いありません。

おそらく資料のタイプミスを見ていると思います。完全ではないケースと完全なケースを区別する、末尾に追加するエントリを見ると、これはおそらくコピー/貼り付けエラーだと思います。テーブルのリードに従って、「配列が「あまりにも空でない」場合はO(1)、O(n)それ以外の場合)」の効果に何かを言う必要があります。 amortized各操作の効率はO(1)であるため、これらの怖いO(n)の用語は実際にあなたを燃やしそうにない各操作が非常に迅速に機能する必要がある特殊な環境にあります。

5
templatetypedef

既に述べたように、混乱を招く可能性があります。動的配列に要素を追加すると、一定の間隔でサイズが変更され、新しい配列が作成されます。そして、サイズが縮小するとき、必要に応じて収縮します。

たとえば、1番目、2番目、3番目、4番目の要素を追加するときに間隔が4の場合、すべては問題ありませんが、5番目の項目の動的配列を追加すると8要素配列に成長し、すべての要素を新しい配列にコピーします。

減少しているときも同じです。間隔が4の5項目配列から1つの項目を削除すると、動的配列は新しい4要素配列を作成し、要素をコピーします。

これが良い表現ビデオです tutorial

はい。動的配列を縮小する必要がないときは、O(1)で、要素を削除するのに必要ですが、すでにわかっているように、O(n)を縮小する必要がある場合です。

大きなO表記を見つけた場合、最悪の場合を定義しているので、O(n)

1
Janith

In Java動的配列(ArrayList)の場合、最後の要素の時間の複雑さの削除はo(1) in Javaコピーしませんarray in Java彼らは、配列インデックスが終了した天気をチェックします。

  int numMoved = size - index - 1;
        if (numMoved > 0)
         //copy array element 
1

挿入と削除は、本質的に固定長であるため、通常アレイでは実行されない操作です。その性質によって固定されているものの長さを増減することはできません。

Javaで「動的配列」について話すとき、彼らはclass ArrayList、これは配列によって支えられており、要素を挿入および削除する機能の錯覚を提供します。

しかし、ソフトウェアの一部がアレイで挿入および削除を実行する錯覚を提供するために、毎回(またはほぼ毎回、最適化が可能です)、新しい望ましい長さの新しいアレイを割り当て、コピーする必要があります削除された要素をスキップするか、場合によっては挿入された要素を追加します。その配列のコピーは、O(N)の由来です。

また、ArrayListによって実行される最適化により、投稿したテーブルは正確ではありません。配列があまり縮小していない場合は、 'O(1)と言う必要があります。O(N)配列が非常に小さくなり、再割り当てが必要であると判断された場合。 'しかし、テーブルセルに収まるには長すぎたと思います。

1
Mike Nakis

私が思う限り、それは動的配列なので、コンピュータシステムはこの動的配列の現在の長さを知らないので、この動的配列の長さを見つけるにはO(n)時間、そしてO(1)最後に要素を削除するのに時間がかかります。

0
Mohd Akbar

動的配列(JavaのArrayList)からアイテムを削除するには、そのアイテムのSearchDelete

要素がリストの最後にある場合、Search自体はn計算時間になります。これがあなたにとって意味があることを願っています。

ソースは http://www.docjar.com/html/api/Java/util/ArrayList.Java.html で表示できます

0
Noman Khan