priority_queue,迭代器和排序

时间:2011-10-11 11:13:28

标签: c++ algorithm

考虑std::priority_queue N个元素具有相同的优先级。现在考虑具有任何优先级的一些pop()push()个元素,以便生成的队列包含上面提到的所有N个元素以及M个新元素,其中所有N+M元素具有相同的优先级。

以下pop()是否保证顶部元素的删除遵循首先删除第一个插入元素的FIFO顺序?

另一个问题是我如何找到一个元素并将其从优先级队列中删除? (赞赏一个简短的例子)

4 个答案:

答案 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()

see here for more description