繁体   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