考慮不同的候選人以及您的假設如何影響最終選擇是有益的。當您的要求發生變化時,切換容器會變得更加容易。
通常,尺寸N
的容器具有其基本ACCES /修改操作大致3複雜類:(攤銷)O(1)
,O(log N)
和O(N)
。
你第一要求(尋找最低權重元素)爲您大致有三種候選人O(1)
的複雜性,以及一名候選人與O(N)
複雜每件:
O(1)
爲std::priority_queue<Element, LowestWeightCompare>
O(1)
for std::multiset<Element, LowestWeightCompare>
O(1)
爲boost::flat_multiset<Element, LowestWeightCompare>
O(N)
爲std::unordered_multiset<Element>
你第二個要求(新元素的隨機插入)提供以下複雜每元件每個上述四種選擇的
O(log N)
爲std::priority_queue
O(log N)
爲std::multiset
O(N)
爲boost::flat_multiset
攤銷O(1)
爲std::unordered_multiset
其中前三種選擇,boost::multiset
應該由另外兩個主導爲大N
。在剩下的兩個中,std::priority_queue
比std::multiset
更好的緩存行爲可能佔上風。但是:措施,措施,措施,但是。
它是模糊的先驗std::unorderd_multiset
是否與其他三個競爭力。取決於隨機插入元件的數量n
,每批的find(1)-insert(n)
總成本將是爲O(N) search + O(n) insertion
和std::unordered_multiset
爲O(1) search + O(n log N) insertion
std::multiset
。再次,測量,測量,測量。
如何強大的是這些因素相對於你的要求?如果您必須在每批中找到k
最低重量元素,則故事會發生如下變化。那麼你必須比較find(k)-insert(n)
的成本。搜索成本將大致規模爲
O(k log N)
爲std::priority_queue
O(1)
爲std::multiset
O(1)
爲boost::flat_multiset
O(k N)
爲std::unordered_multiset
注意,一個priority_queue
只能有效地訪問頂部元素,而不是它的k
頂部元素,實際上並沒有調用pop()
,每個調用的複雜度爲O(log N)
。如果你希望你的代碼可能會從find(1)-insert(n)
批處理模式更改爲find(k)-insert(n)
,那麼它可能是一個好主意,選擇std::multiset
,或至少文檔什麼樣的接口的改變,將需要。
獎勵:兩全其美的?你也可能要實驗一下與Boost.MultiIndex和使用類似(查看文檔,以獲得語法正確的)
boost::multi_index<
Element,
indexed_by<
ordered_non_unique<member<Element, &Element::weight>, std::less<>>,
hashed_non_unique<>
>
>
上面的代碼將創建一個實現兩個指針結構跟蹤基於節點的容器這兩個按重量排序的Element
也允許快速哈希插入。這將允許O(1)
查找最低重量Element
的同時還能夠n
新元素O(n)
隨機插入。
對於大型N
,它應該規模比四個前面提到的容器好,但同樣,通過指針追成隨機內存可能會破壞在std::priority_queue
它的理論優勢誘導適度N
,緩存的效果。我有沒有提到措施,措施,措施的口頭禪?
你能詳細說明「時間關鍵」部分嗎?它只是需要儘快發生的結構集合嗎?將它們存儲在容器中?他們的處理?混合物?還有別的嗎? –
@Joachim:應用程序對時間至關重要,因爲整個提取/過程/插入序列必須在有限且儘可能短的時間內執行。 – shrike