簡體   English   中英

列表或容器O(1) - 插入/刪除性能,具有數組語義

[英]list or container O(1)-ish insertion/deletion performance, with array semantics

我正在尋找一個提供列表語義的集合,但也允許數組語義。 假設我有一個包含以下項目的列表:

apple orange carrot pear 

然后我的容器數組將:

container[0] == apple 
container[1] == orangle 
container[2] == carrot 

然后說我刪除了橙色元素:

container[0] == apple 
container[1] == carrot 

我想在不必顯式調整大小的情況下折疊數組中的間隙,即如果我刪除容器[0],則容器會崩潰,因此容器[1]現在被映射為容器[0]和容器[2]作為容器[1]等我仍然需要使用數組語義訪問列表,並且不允許空值(在我的特定用例中)。

編輯:

回答一些問題 - 我知道O(1)是不可能的,但我不希望容器的數組語義接近O(log N)。 排序失敗的目的,我可以迭代列表。

我原本在排序順序上有一些措辭,我不確定我當時的想法(星期五啤酒時鍾最有可能)。 其中一個用例是包含圖像的Qt列表 - 從列表中刪除圖像應該折疊列表,不必從列表中取出最后一項並將其放入其中。 在這種情況下,我確實想要保留列表語義。

我看到的關鍵差異是分隔列表和數組:數組 - 常量時間訪問列表 - 任意插入

如果重新平衡使迭代器失效,我也不會過分擔心。

您可以執行ArrayList / Vector(Java / C ++),當您刪除時,首先將最后一個元素與deleted元素交換。 因此,如果您有ABCDE,並且您刪除了C,那么您最終將使用ABE D.請注意,對E的引用現在必須查看2而不是4(假設0已編入索引),但您說排序順序不是問題。

我不知道它是否自動處理(優化后可以輕松地從最終刪除),但如果不是,你可以輕松編寫自己的數組包裝類。

O(1)可能要求太多。

O(logn)插入/刪除/訪問時間是否正常? 然后你可以得到一個平衡的紅黑樹,其中包含訂單統計數據: http//www.catonmat.net/blog/mit-introduction-to-algorithms-part-seven/

它允許您按位置插入/刪除/訪問元素。

正如Micheal所指出的那樣,Java Treemap支持它: http//java.sun.com/j2se/1.5.0/docs/api/java/util/TreeMap.html

另外,不確定為什么你認為O(logN)和迭代列表一樣糟糕!

從我對你的其他答案的評論:

對於100萬件物品,使用平衡的紅黑樹,最壞的情況是2log(n + 1),即~40。 你需要做的不超過40比較找到你的元素,這是絕對最壞的情況。 紅黑樹也迎合洞/間隙消失。 這比迭代列表提前了幾英里(平均約為1/2萬!)。

使用AVL樹而不是紅黑樹,最壞的情況保證甚至更好:1.44 log(n + 1),對於一百萬個項目是~29。

你應該使用一個HashMap ,你將有O(1) - 預期的插入時間,只需要從整數到任何地方進行映射。

如果訂單不重要,那么vector就可以了。 訪問是O(1),使用push_back插入,並刪除如下:

swap(container[victim], container.back());
container.pop_back();

編輯:剛剛注意到問題是標記為C ++和Java。 這個答案僅適用於C ++。

我不知道任何提供O(1)隨機訪問,插入和刪除的數據結構,所以我懷疑你必須接受一些權衡。

Java中的LinkedList提供從列表的頭部或尾部的O(1)插入/刪除是O(1) ,但是隨機訪問是O(n)

ArrayList提供O(1)隨機訪問,但插入/刪除只是列表尾部的O(1) 如果從列表中間插入/刪除,則必須移動列表中的其余元素。 從好的方面來說,它使用System.arraycopy來移動元素,我的理解是這在現代架構上基本上是O(1) ,因為它實際上只是復制內存塊而不是單獨處理每個元素。 我說的主要是因為仍然有工作要找到足夠的連續自由空間塊等等,而且我不確定那個大O可能是什么。

既然你似乎想在(接近)恆定時間插入任意位置,我認為使用std::deque是你在C ++中最好的選擇。 std::vector不同,deque(雙端隊列)被實現為內存頁面列表,即分塊矢量。 這使得在任意位置插入和刪除是一個恆定時間操作(僅取決於雙端隊列中使用的頁面大小)。 數據結構還在接近恆定的時間內提供隨機訪問(“數組訪問”) - 它必須搜索正確的頁面,但這在實踐中是非常快速的操作。

Java的標准容器庫不提供類似的東西,但實現很簡單。

Concurent SkipList Map怎么樣? 它做O(Log N)?

http://research.swtch.com/2008/03/using-uninitialized-memory-for-fun-and.html中描述的數據結構是否可以執行您想要的任何操作?

暫無
暫無

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

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