优先级队列如何在推送操作期间比较和存储值
How does Priority queue compare and store the values during the push operation?
我正在处理优先级队列,我想检查如何使用可比较的类来比较值。这是我的代码。
#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 进行比较?谁能帮忙?
优先级队列通常实现为完美平衡的堆结构。堆可以看作是一个二叉树,唯一的要求是根的优先级高于其子级(比较器的值较小),即堆条件。
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。 其他包括一棵红黑树。
这也可能有助于提高STL的效率priority_queue
std::priority_queue<...>
在内部表示为 d 堆。表示形式使用树,其中每个子树的根在此子树中具有最高优先级。它的结构旨在最大限度地减少必要的比较数量。
插入元素时,它入树的底部,并沿着根的路径与父级交换,只要它具有更高的优先级。删除将根与叶交换,删除叶,然后将根与子树的最高优先级子级交换,只要其优先级较低。
相关文章:
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 比较存储在 std::string 中的数据中的字节数
- std::unordered_map如何存储和比较其密钥,以实现无需订购即可快速访问元素?
- 短(ASCII,每个字符 7 位)字符串存储和C++中的比较优化
- 如何正确比较存储在内存中的两个数组?
- 比较存储分子和分数的分母
- 2D阵列和1D阵列存储比较
- 将当前时间 simTime.dbl() 与以前存储的双精度值进行比较并不总是给出正确的答案......为什么?
- 比较存储在向量中的类对象的私有成员变量 - C++
- "Flattening" std::set<std::string> 用于存储和比较?
- 将用户输入与矢量中存储的值进行比较
- 如何比较和存储 2 个向量的数据元素位置
- 如何使用SIMD比较两个字符向量并将结果存储为浮点值
- 比较从父类继承但存储在父类的向量中的类的对象类型
- 如何存储坐标以便与以后的坐标进行比较
- 如何在c++骰子游戏中存储第一个值,并在下一步进行比较
- 无法存储 stdin 状态并在C++中进行比较
- 如何使用 OpenCV 比较存储在文件中的两个图像
- 比较存储在boost::function中的函数指针
- Lua函数在使用Luabind比较存储的C++对象指针时崩溃