簡體   English   中英

priority_queue,迭代器和排序

[英]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.

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