[英]priority_queue, iterator and ordering
考慮一個std::priority_queue
,其中N
元素具有相同的優先級。 現在考慮一些具有任何優先級的元素的pop()
和push()
,以便生成的隊列包含上面提到的所有N
元素加上M
新元素,其中所有N+M
元素具有相同的優先級。
下面的pop()
是否保證頂部元素的刪除遵循首先刪除第一個插入元素的FIFO順序?
另一個問題是如何找到一個元素並將其從優先級隊列中刪除? (贊賞一個簡短的例子)
我認為沒有這樣的保證。 根據sgi的文檔 ,它取決於底層的數據結構。
我認為大多數常見的實現使用堆。 推送和彈出堆上的任何項只會更新其中的元素,使得其子節點不大於父節點(對於最大堆)。 在兩個孩子具有相同優先級並且其中一個必須取代父母的情況下,在選擇要促進的節點方面沒有區別。 因此,選擇左側或右側節點完全取決於實現。
如果所有優先級相等,確實需要以FIFO順序存在節點,則傳入首先按優先級排序的比較函數,並使用存儲在對象中的值來斷開關系,該對象包含在其之前被推入priority_queue的對象數量。
int cmp(my_object a, my_object b){
if (a.priority!=b.priority) return a.priority<b.priority;
else return a.index<b.index;
}
如何找到一個元素並將其從優先級隊列中刪除? (贊賞一個簡短的例子)
您不像在地圖或集合中那樣“查找”優先級隊列中的元素...而是它是一個隊列,隊列的行為是刪除隊列前面的元素,並推送新元素隊列的后面。 訪問隊列中間的元素與預期的行為不同(如果您修改了該對象,將會/可能嚴重破壞預期的行為模式)。 在優先級隊列的情況下,元素被排序,因此隊列中的第一個元素是具有最高優先級的元素,或者,如果所有元素具有相同的優先級,則它返回到您的第一個問題,即“ no“,不能保證按FIFO順序,因為許多實現使用堆排序,並且排序的結果對於具有相同優先級的對象將是不明確的,因為堆是二叉樹的線性表示(也就是說,對於兩個相等的子對象,在pop()
期間從隊列中刪除根節點時,在根的兩個子節點之間選擇作為新的根節點時會出現模糊的選擇...換句話說,對象是相同的優先級將組合在一起,但從隊列中彈出的順序可能不是FIFO順序。 您可以在此處查看該操作的快速示例: http : //ideone.com/DjSDi
您可以/應該使用標准列表(或向量)和make_heap,push_heap,pop_heap來模擬(雙端)優先級隊列。
這將為您提供更多選擇。 (包括您描述的操作類型)。 但是,您必須自己實現邏輯。
通常,標准容器適配器(stack,priority_queue)在其公開的操作集中是限制性的。
1-如果要在元素具有相同優先級時強制執行FIFO排序,請在類中添加字段t
(在元素添加到優先級隊列時表示)和運算符<compare t如果兩個元素具有相同的優先級。
或者你可以使用pair< T , int >
當T是你的元素的類型時,當t是一個整數時,你將int設置為t,當你向你的優先級隊列添加一些東西時 - 它。
2-您無法訪問優先級隊列中的任何其他元素。 你只能使用:
constructor
top()
pop()
push()
size()
empty()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.