You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ pair<int,int>优先队列自定义比较器异常及与vector差异问题

priority_queue与sort自定义比较器逻辑一致但结果相反的原因及解决

问题场景

想要实现一个存储pair<int,int>的priority_queue,规则是:首元素降序,首元素相同时次元素升序。编写的代码如下:

#include <bits/stdc++.h>

using namespace std;

struct Comp
{
    bool operator()(pair<int, int> const& p1, pair<int, int> const& p2)
    {
        if (p1.first == p2.first)
        {
            return p1.second < p2.second;
        }
        else
        {
            return p1.first > p2.first;
        }
    }
};

int main()
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, Comp> pq;

    pq.push(make_pair(3, 5));
    pq.push(make_pair(2, 4));
    pq.push(make_pair(1, 6));
    pq.push(make_pair(3, 2));
    pq.push(make_pair(2, 2));

    while (!pq.empty())
    {
        pair<int, int> p = pq.top();
        cout << p.first << " " << p.second << endl;
        pq.pop();
    }

    return 0;
}

预期输出:

3 2
3 5
2 2
2 4
1 6

实际输出却完全相反:

1 6
2 4
2 2
3 5
3 2

但将相同逻辑的比较器用于vector的sort函数时,却能得到正确结果:

#include <bits/stdc++.h>

using namespace std;

bool comp (pair<int, int> const& p1, pair<int, int> const& p2)
{
        if (p1.first == p2.first)
        {
            return p1.second < p2.second;
        }
        else
        {
            return p1.first > p2.first;
        }
}

int main()
{
    vector<pair<int,int> > v;

    v.push_back(make_pair(3, 5));
    v.push_back(make_pair(2, 4));
    v.push_back(make_pair(1, 6));
    v.push_back(make_pair(3, 2));
    v.push_back(make_pair(2, 2));

    sort(v.begin(), v.end(), comp);

    for(int i=0; i<v.size(); i++)
    {
        cout << v[i].first << " " << v[i].second << endl;
    }
    return 0;
}

输出结果符合预期:

3 2
3 5
2 2
2 4
1 6

核心原因

两者的比较器逻辑定义本质完全不同:

  • sort的比较器:返回true时,表示p1应该排在p2的前面,直接定义元素的顺序优先级。
  • priority_queue的比较器:返回true时,表示p1的优先级低于p2,会被放在堆的下层(即p2会被优先弹出)。它本质是定义堆的弱序关系,用来判断元素是否需要"下沉"。

直白来说:sort的比较器是判断"谁该在前",priority_queue的比较器是判断"谁该被压下去"。你写的比较器逻辑在sort里是让大的首元素在前,但在priority_queue里,这个逻辑会让大的首元素被判定为优先级更低,被压到堆底,最终弹出顺序就完全反过来了。

解决方案

翻转priority_queue比较器里的判断逻辑,让它符合堆的弱序规则即可:

#include <bits/stdc++.h>

using namespace std;

struct Comp
{
    bool operator()(pair<int, int> const& p1, pair<int, int> const& p2)
    {
        if (p1.first == p2.first)
        {
            // 首元素相同时,次元素大的优先级更低,应该被压下去
            return p1.second > p2.second;
        }
        else
        {
            // 首元素小的优先级更低,应该被压下去
            return p1.first < p2.first;
        }
    }
};

int main()
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, Comp> pq;

    pq.push(make_pair(3, 5));
    pq.push(make_pair(2, 4));
    pq.push(make_pair(1, 6));
    pq.push(make_pair(3, 2));
    pq.push(make_pair(2, 2));

    while (!pq.empty())
    {
        pair<int, int> p = pq.top();
        cout << p.first << " " << p.second << endl;
        pq.pop();
    }

    return 0;
}

运行后输出符合预期:

3 2
3 5
2 2
2 4
1 6

内容的提问来源于stack exchange,提问作者amp1590

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:35:40