考虑std::priority_queue
N
个元素具有相同的优先级。现在考虑具有任何优先级的一些pop()
和push()
个元素,以便生成的队列包含上面提到的所有N
个元素以及M
个新元素,其中所有N+M
元素具有相同的优先级。
以下pop()
是否保证顶部元素的删除遵循首先删除第一个插入元素的FIFO顺序?
另一个问题是我如何找到一个元素并将其从优先级队列中删除? (赞赏一个简短的例子)
答案 0 :(得分:3)
我认为没有这样的保证。根据{{3}},它取决于底层数据结构。
我认为大多数常见的实现都使用堆。推送和弹出堆上的任何项只会更新其中的元素,使得其子节点不大于父节点(对于最大堆)。在两个孩子具有相同优先级并且其中一个必须取代父母的情况下,在选择要促进的节点方面没有区别。因此,选择左侧或右侧节点完全取决于实现。
如果所有优先级相等,确实需要以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;
}
答案 1 :(得分:2)
如何找到元素并将其从优先级队列中删除? (赞赏一个简短的例子)
你没有像在地图或集合中那样“找到”优先级队列中的元素......而是它是一个队列,队列的行为是删除队列前面的元素,然后推送队列背面的新元素。访问队列中间的元素与预期的行为不同(如果您修改了该对象,将会/可能严重破坏预期的行为模式)。在优先级队列的情况下,元素被排序,因此队列中的第一个元素是具有最高优先级的元素,或者,如果所有元素具有相同的优先级,则它返回到您的第一个问题,即“ no“,不能保证按FIFO顺序,因为许多实现使用堆排序,并且排序的结果对于具有相同优先级的对象将是不明确的,因为堆是二叉树的线性表示(也就是说,对于两个相等的子对象,在pop()
)期间从队列中删除根节点时,在根的两个子节点之间选择作为新的根节点时会出现模糊选择...换句话说,对象具有相同优先级的数据将组合在一起,但从队列中弹出的顺序可能不是FIFO顺序。您可以在此处查看该操作的快速示例:http://ideone.com/DjSDi
答案 2 :(得分:0)
您可以/应该使用标准列表(或向量)和make_heap,push_heap,pop_heap模拟(双端)优先级队列。
这会为您提供更多选择。 (包括您描述的操作类型)。但是,您必须自己实现逻辑。
通常,标准容器适配器(stack,priority_queue)在其公开的操作集中是限制性。
答案 3 :(得分:0)
1-如果要在元素具有相同优先级时强制执行FIFO排序,请在类中添加字段t
(当元素添加到优先级队列时),并在运算符&lt;比较t如果两个元素具有相同的优先级。
或者当T是你的元素类型时你可以使用pair< T , int >
当t是一个整数时你将int设置为t,当你向你的优先级队列添加一些东西时它就是。
2-您无法访问优先级队列顶部的任何其他元素。你只能使用:
constructor
top()
pop()
push()
size()
empty()