【发布时间】:2021-05-12 09:55:03
【问题描述】:
我正在构建一个具有以下要求的最低优先级队列:
- 元素具有单独的优先级映射。
- 可以使用更新的优先级再次插入索引,插入后“旧”索引的位置并不重要。
下面是一个演示意外结果的最小示例。在代码中,我分别将优先级队列1、2 和3 插入优先级队列10、20 和30。然后我将优先级20 -> 5 更改为索引2,并再次插入。
#include <map>
#include <queue>
#include <stdio.h>
int main() {
std::map<int, int> weight;
weight[1] = 10;
weight[2] = 20;
weight[3] = 30;
auto compare = [&](int left, int right) { return weight[left] > weight[right]; };
std::priority_queue<int, std::vector<int>, decltype(compare)> queue(compare);
queue.push(1);
queue.push(2);
queue.push(3);
weight[2] = 5;
queue.push(2);
while (!queue.empty()) {
printf("%i ", queue.top());
queue.pop();
}
}
运行上面的代码会得到输出1 2 2 3。我希望这会输出2 2 1 3 或者可能是2 1 2 3。奇怪的是,将 weight[2] = 5; 更改为 weight[2] = 35; 会得到预期的输出 1 3 2 2。根据 cppreference,这是作为二进制堆实现的,但我不明白为什么我会得到第一个结果。
【问题讨论】:
-
因为数据结构不支持。它已经按照自己的顺序保存了数据,并且它不知道您更改了它。您需要删除并重新插入该项目。
-
'优先级队列不应该知道任何特定的优先级值......它只知道一个是否大于另一个':当然:如果你改变这种关系而不告诉它,你把它弄坏了。就像你在这里一样。
标签: c++ priority-queue