簡體   English   中英

stl deque :: insert()的復雜性

[英]Complexity of stl deque::insert()

我從C ++標准2003(第23.2.1.3章)中了解了deque::insert()的復雜性,如下所示:

在最壞的情況下,將單個元素插入到雙端隊列中需要時間在從插入點到雙端隊列開始的距離的最小值以及從插入點到雙端隊列結束的距離的線性。

我總是將stl deque的實現理解為內存塊的集合。 因此,插入僅影響與插入位置相同的存儲塊中的元素。 我的問題是,標准是什么意思是“從插入點到雙端隊列開始的距離的最小值和從插入點到雙端的終點的距離”是什么?

我的理解是因為C ++標准沒有強制實施deque的某種實現。 對於最壞的情況,復雜性通常是一般的。 但是,在編譯器的實際實現中,它與內存塊中的元素數量成線性關系,這可能因不同的元素大小而異。

另一個猜測可能是,因為insert()將使所有迭代器無效,deque需要更新所有迭代器。 因此它是線性的。

std :: deque通常(總是?)實現為內存塊的集合, 它通常不會插入一個全新的塊,只是為了在集合的中間插入一個新元素。 因此,它將查找插入點是否更接近開頭或結尾,並對現有元素進行隨機播放,以便為現有塊中的新元素騰出空間。 它只會在集合的開頭或結尾添加一大塊內存。

我認為你的圖表會更好...讓我們玩ASCII藝術!

deque通常是一組內存塊,但前后內存塊都是完整的。 這是必要的,因為deque是RandomAccessContainer,並且為了獲得對任何容器的O(1)訪問,您不能擁有無限數量的容器來讀取大小:

bool size() const { return first.size + (buckets.size()- 2) * SIZE + last.size; }

T& operator[](size_t i) {
  if (i < first.size) { return first[SIZE - i]; }

  size_t const correctedIndex = i - first.size;
  return buckets[correctedIndex / SIZE][correctedIndex % SIZE];
}

由於乘法/除法,這些操作是O(1)!

在我的例子中,我假設當一個內存塊包含8個元素時它已滿。 在實踐中,沒有人說尺寸應該固定,只是所有內桶應具有相同的尺寸。

 // Deque
 0:       ++
 1: ++++++++
 2: ++++++++
 3: ++++++++
 4: +++++

現在說我們想要在索引13處插入它。它位於標記為2的桶中。我們可以考慮幾種策略:

  • 擴展桶2(僅)
  • 在2之前或之后引入一個新的桶,並且只需要洗幾個元素

但是這兩種策略會違反所有“內部”桶具有相同數量元素的不變量。

因此,在我們的情況下,我們將左右的元素拖到開頭或結尾(以較便宜的價格為准):

 // Deque
 0:      +++
 1: ++++++++
 2: +O++++++
 3: ++++++++
 4: +++++

注意桶0如何增長。

這種混洗意味着,在最壞的情況下,你將移動一半的元素:O(N / 2)。

deque在開頭或結尾插入O(1),因為只需在正確的位置添加元素或(如果存儲桶已滿)創建新存儲桶。

基於B +樹 ,還有其他容器在隨機索引處具有更好的插入/擦除行為。 在索引的B +樹中,您可以而不是“鍵”(或並行)在內部維護某個位置之前的元素計數。 有效地執行此操作有各種技術。 最后你得到一個容器:

  • O(1):空,大小
  • O(log N):at,insert,erase

您可以在Python中檢查blist模塊,該模塊實現了由此類結構支持的類似Python列表的元素。

你的推測是...... 99.9%是真的。 一切都取決於實際的實施。 標准規定的是兩個實現者的最低要求(如果他們不符合規范,則不能聲稱是標准的)和用戶(如果編寫與實現無關的代碼則不能期望“更好的性能”)。

規范背后的想法是一個未初始化的內存塊(一個==一個),其中元素分布在中心周圍......直到它們有空間。 插入中間意味着移位。 在前端或末端插入意味着只需構建到位。 (當不存在空間時,重新分配完成)修改后不能信任索引和迭代器,因為我們不能假設已經移位的內容和方向。

更有效的實現不使用單個塊,而是使用多個塊來重新分配“移位”問題並從底層系統分配恆定大小的內存(從而限制重新分配和分段)。 如果你的目標是其中一個,你可以期待更好的表現,否則你最好不要假設任何結構優化。

線性插入的元素數量(復制構造)。 另外,根據特定的庫實現,額外的線性時間可以達到位置和雙端隊列之一之間的元素數量。 參考...

暫無
暫無

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

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