簡體   English   中英

為什么在動態數組O(n)時間復雜度結束時刪除項?

[英]Why is deletion of an item at end of Dynamic array O(n) time complexity?

我目前正在閱讀我的教科書,我很困惑為什么動態數組需要O(n)時間來刪除最后的項目。 我知道從任何其他索引中刪除一個項目是O(n),因為你必須復制所有數據並移動它們以填補空白,但如果它最后不是我們只是減少計數並設置索引喜歡0還是null? 我在書中加了一張照片。 這很奇怪,因為它說索引是O(1)所以我們必須知道項目的位置,所以我們不必像鏈表一樣遍歷數組。 在此輸入圖像描述

首先,讓我們通過“動態數組”查看書籍的含義:

動態數組(也稱為可增長數組可調整大小數組動態表數組列表 )是一種隨機訪問,可變大小的列表數據結構,允許添加或刪除元素。 [...]
注意:我們將在Stacks,Queues和Hashing章節中看到動態數組的實現。

由此我們了解到,數組列表是“動態數組”的示例,正​​如本書的作者所定義的那樣。

但進一步看,這本書提到:

一旦該數組變滿,就創建一個比原始數組大兩倍的新數組。 同樣, 如果數組中的元素小於一半則將數組大小減小到一半

(我強調的是)

Java ArrayList不會這樣做 - 刪除元素時它不會減少存儲空間。 但作者正在談論(或認為ArrayList確實)減少了數組大小。 在這種情況下,從最糟糕的情況來看,你可以說復雜性是O(n)因為減小大小涉及將n元素復制到簡化的數組。

結論:

雖然對於Java ArrayList實現來說並不是這樣,但是當本書的作者在必要時討論“刪除數組大小”的“動態數組”時, 那么數組末尾刪除的最壞情況復雜性確實如此。 O(n)

這個條目似乎也是如此

  1. 不正確,或
  2. 是的,但有誤導性。

你是完全正確的,你可以在動態數組中的最終位置銷毀對象,然后減小大小以刪除最后一個元素。 在動態數組的許多實現中,有時需要執行調整大小操作以確保分配的數組的大小在元素數量的某個常數因子內。 如果發生這種情況,那么是的,您需要創建一個新數組,復制舊元素,然后釋放前一個數組,這需要花費時間O(n)。 但是,您可以證明這些調整大小非常罕見,以至於從末尾執行刪除的平均成本是O(1)。 (在更技術性的意義上,我們說從末端刪除元素的攤銷成本是O(1))。 也就是說,只要您只關心執行一系列操作的總成本而不是任何單個操作的成本,那么假裝每個操作花費您的時間O(1)就沒有錯。

我會說你最有可能看到材料中的拼寫錯誤。 看看他們的條目是否附加到最后,它區分了非完整和完整的案例,我認為這可能是一個復制/粘貼錯誤。 在表的引導之后,應該說“O(1)如果數組不是'太空,'O(n)否則。” 但同樣,請記住,每個操作的攤銷效率為O(1),這意味着這些可怕的O(n)術語實際上不太可能在實踐中燒傷你,除非你處於每個操作需要的專門環境中工作真的很快。

在java for Dynamic array(ArrayList)中刪除最后一個元素的時間復雜度是o(1)在java中它不復制數組在java中它們會檢查天氣數組索引是否結束。

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

插入和刪除是我們通常不對數組執行的操作,因為它們本質上具有固定長度。 你不能增加或減少由其性質決定的東西的長度。

當人們在Java中談到“動態數組”時,他們傾向於使用由數組支持的class ArrayList ,它提供了插入和刪除元素的錯覺。

但是為了讓某些軟件提供在陣列上執行插入和刪除的錯覺,每次(或幾乎每次都有可能的優化)它必須分配新的所需長度的數組,並復制將舊數組放入其中,跳過已刪除的元素或根據具體情況添加插入的元素。 該數組副本是O(N)的來源。

並且,由於ArrayList執行的優化,您發布的表不准確:如果數組沒有縮小太多,則應該說'O(1),如果數組收縮太多則應該說O(N)重新分配被認為是必要的'。 但我想這可能太長了,不適合表格單元格。

正如您所提到的,這可能會令人困惑,如果您向動態數組添加元素,它會以恆定間隔更改其大小,並將為您創建一個新數組,您可能已經知道新數組的復制元素。 當它縮小尺寸時,如果需要也會推卸。

例如,當你添加第1,第2,第3,第4個元素時間隔為4時,一切都會好的,但是當你添加第5個項目時,動態數組會變成8個元素數組並將所有元素復制到新數組。

它在減少時是一樣的。 如果從間隔為4的5項數組中刪除一個項,則動態數組將創建一個新的4個元素數組並復制這些元素。

這是一個很好的代表視頻教程

是。 當動態數組不必縮小時,它是移除元素所需的O(1),但是當它必須縮小其O(n)時,正如您可能已經想到的那樣。

當你發現大O符號你定義最壞的情況時,它就是O(n)

據我所知,因為它是一個動態數組,所以計算機系統不知道這個動態數組的當前長度是多少,所以要找到這個動態數組的長度需要O(n)時間,然后取O( 1)在結束時刪除元素的時間。

從動態數組中刪除項目(java中的ArrayList)需要搜索項目而不是刪除

如果元素位於列表的末尾,則搜索本身將導致n計算時間。 我希望這對你有意義。

您可以在http://www.docjar.com/html/api/java/util/ArrayList.java.html上查看來源

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM