[英]std::set erase complexity anomality?
我試圖弄清楚從std :: set中刪除多個元素的復雜性。 我正在使用此頁面作為來源。
它聲稱使用迭代器擦除單個項目的復雜性是分攤O(1),但使用范圍形式擦除多個項目是log(c.size())+ std :: distance(first,last)(即 - 集合大小的日志+刪除的元素數量)。
從面值來看,如果要擦除的元素的數量(n)遠小於集合(m)中的元素的數量,則這意味着在要擦除的元素上循環並且一次擦除它們的速度更快(O(n))比用一次調用擦除它們(假設n << m)為O(log m)。
顯然,如果真的如此,第二種形式的內部實現只會做上述循環。
這是網站上的錯誤嗎? 規格中的錯誤? 我只是錯過了一些東西嗎?
謝謝,Shachar
似乎問題隱藏在(有些狡猾的)“攤銷”這個詞背后。 單項擦除具有O復雜度log(c.size()),但是O(1)的攤銷復雜度。
因此,在循環中執行多個單個擦除將花費log(c.size())+擦除次數,這正是范圍形式的復雜性。
Shachar
集合的內部元素存儲在平衡二叉樹中。 平衡樹是一棵樹,其中任何節點的任何左右子樹之間的最大高度差為1。
保持平衡結構對於保證搜索樹中(在集合中)中的任何元素都采用最壞情況下的O(log(n))
步驟是很重要的。
去除元素可能會破壞平衡。 要恢復平衡,必須執行旋轉。 在某些情況下,單次移除會導致多次旋轉,因此操作需要O(log(n))
步,但平均而言,移除需要O(1)
步。
因此,當必須逐個刪除分散在集合上的多個元素時,具有高概率的攤銷成本將是每次移除O(1)
。
刪除范圍內的幾個元素( first, last
一個元素,其中一個元素跟隨下一個元素)幾乎肯定會破壞平衡,導致復雜性中的對數因子: log(n) + std::distance(first, last)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.