我正在处理优先级队列,我想检查使用类似的类比较值的方式。这是我的代码。
#include <iostream>
#include <queue>
using namespace std;
class g {
public:
bool operator() (int a, int b) {
cout<<a<<" "<<b<<endl;
return (a > b);
}
};
int main() {
priority_queue<int,vector<int>,g> p;
p.push(2);
cout<<"CHECK1"<<endl;
p.push(4);
cout<<"CHECK2"<<endl;
p.push(8);
cout<<"CHECK3"<<endl;
p.push(1);
cout<<"CHECK4"<<endl;
while(!p.empty()) {
cout<<p.top()<<endl;
p.pop();
}
}
输出
CHECK1
2 4
CHECK2
2 8
CHECK3
4 1
2 1
CHECK4
1
8 2
2 4
2
4 8
4
8
我看到当推入4时,它与2进行比较,当推入8时,它再次与2进行比较。但为什么8不与4相比? 有人可以帮忙吗?
答案 0 :(得分:2)
优先级队列通常实现为完美平衡的堆结构。堆可以看作是一个二叉树,唯一要求根的优先级(比较器的值小于其子节点,堆条件)。
root
Lchild1 Rchild1
Lchild2 Rchild2 Lchild2 empty
任何插入都插入空白点以保持树的平衡。插入后,它将向上移动树以保持堆状态。所以在这种情况下,唯一可能的比较是Rchild1和root。
删除/ pop()是通过删除Lchild2中的根和交换来完成的,以保持完美的平衡,然后将Lchild2移到堆中以纠正堆状况。
这棵树很容易保存在矢量中。
root(2)
Lchild1(4) empty.
插入8(在空白处)只需要与根进行比较。
root(2)
Lchild1(4) Rchild1(8).
empty
在空白处插入1,需要检查4并交换,然后与根(和交换)进行比较。
有很多可能的内部表示,例如参见https://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/pq_performance_tests.html。其他包括红黑树。
答案 1 :(得分:1)
std::priority_queue<...>
在内部表示为d-heap。该表示使用树,其中每个子树的根在该子树中具有最高优先级。它的结构可以最大限度地减少必要的比较次数。
插入元素时,它会插入树的底部,并且只要具有更高的优先级,就会沿着到根的路径与父母交换。删除与叶子交换根,删除叶子,然后只要优先级较低,就将根与子树的最高优先级子进行交换。