C++ 自定义排序与优先队列运算符重载
一、优先队列的底层逻辑 (Worldview)
1. 核心矛盾:为什么用 < 却是'大根堆'?
std::priority_queue 的行为逻辑与其命名看似矛盾,实则遵循了 STL 的一致性设计。
- 默认属性:
priority_queue= Max Heap (大根堆)。 - 默认判据:
std::less(即调用operator<)。 - 判定流程:
- 队列内部比较
a和b。 - 调用
a < b。 - 若返回 True,判定
b比a强 (在默认的大根堆语境下,数值大的被视为'强')。 - 结果:强者 (
b) 上浮至堆顶。
- 队列内部比较
2. 代码
// 代码逻辑 friend bool operator<(node a,node b){ return a.z<b.z; }
解析:遵循默认逻辑。z 越大,< 比较时在右侧越显'强',因此 z 最大的在堆顶。
二、优先队列的三种实战写法 (Friend 友元版)
统一使用 Friend (友元) 写法,该写法无 this 指针干扰,逻辑对称,不易出错。
方案 1:大根堆 (默认流)
- 场景:贪心求最大值、常规逻辑。
- 效果:大的先出 (9 -> 8 -> 1)。
struct node{
int z;
// 逻辑:a.z < b.z 为真 -> b 强 -> b 在顶
friend bool operator<(node a,node b){ return a.z<b.z; }
};
// 声明:使用默认的大根堆机制
priority_queue<node> q;
方案 2:小根堆 (竞赛黑科技流)
- 场景:Dijkstra 最短路、Prim、Huffman 树。
- 原理:逻辑欺骗。通过反转布尔值,让队列误以为'数值小'的才是'强者'。
- 效果:小的先出 (1 -> 2 -> 9)。
struct {
z;
<(node a,node b){ a.z>b.z;
};
priority_queue<node> q;

