簡體   English   中英

std :: deque :: erase函數的時間復雜度是多少?

[英]What is the time complexity of std::deque::erase function?

在這里,它說明了時間的復雜性:

線性刪除的元素數(破壞)。 另外, 取決於特定的庫實現 ,在位置與雙端隊列的兩端之間的元素數量上,最多需要額外的線性時間。

從第一句話我知道,如果要刪除雙端隊列中的任何數字,則最壞情況下的復雜度將為O(1)。

現在第二句話使我感到困惑。 取決於特定的庫實現是什么意思? 我正在使用STL庫,該庫與GCC編譯器一起提供。 在我的情況下,如何學習此函數的正確時間復雜度?

我需要將其設置為O(1),因為我正在運行O(n)擦除調用,如果std::deque::erase為O(n),我的算法將具有二次復雜度,這是我不想要的。

如果必須從雙端隊列中刪除n項目,通常需要使用remove/erase習慣用法。

您從std::remove開始刪除n項本身。 這基本上將您的集合分為兩部分:一開始是您沒有刪除的部分,另一部分是您不再關心的內容。

它返回一個指向這兩個邊界的迭代器。 然后,您可以從那里擦除到結尾(一次),以擺脫不再關心的項目。

std::remove基本上執行了我認為的“波紋復制”操作-從頭到尾遍歷整個集合,當找到要刪除的項目時,它會找到要保留的下一個項目,並且將其復制到要刪除的文件1

如果您不需要維護所保存物品的順序,則通常可以進一步提高速度。 從集合的開頭開始,找到您要刪除的項目(即,您當前要erase )。 年底開始找到你想要保存項目(即,一個你不會 erase )。 交換這兩個項目,然后繼續“向內”搜索,直到兩個位置相遇。 現在,您要刪除的所有項目都在集合的末尾。 您可以在O(1)中刪除所有它們。

從理論上講,這兩者的總體復雜度是相同的-均為O(N)。 但是,在許多情況下,復制項目是相對昂貴的(相對於僅確定是否保留該項目)。 這樣可以最大程度地減少要復制/移動的項目的數量,因此,當復制/移動的成本很高時,可以節省大量時間(盡管,如前所述,如果其余對象的順序很重要,則不合適)。


  1. 請注意,從C ++ 11開始,這些可以是移動而不是副本(例如,如果提供了移動迭代器)。

cplusplus.com涵蓋了C ++標准庫,而不是原始的STL。 C ++ stdlib包含了大部分 STL,並且它具有幾種實現方式,這些實現通常(如果不是始終如此)從STL代碼派生而來,但可以通過各種方式對其進行更改。 實際上,GCC實現是對STL + GNU的修改。 根據該標准, deque中的erase可以是線性的。

如果您想了解實現過程中此操作的復雜性,請閱讀手冊 (盡管我在任何地方都找不到deque ),閱讀源代碼或配置文件。

暫無
暫無

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

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