C++优先级队列中的多次比较

C++优先级队列中的多次比较

优先级队列(Priority Queue)是一个自动排序的容器,在C++ STL中有相关实现,常用于解决优先级问题。默认情况下,C++ STL中的优先级队列是按照元素大小进行比较排序的,但当我们需要对元素进行多次比较时,就需要在定义队列时传入比较函数来实现自定义排序。

默认的比较

首先,让我们看一下默认情况下的优先级队列的比较规则。假设我们定义了一个存储整数的优先级队列:

#include <iostream>
#include <queue>
using namespace std;

int main()
{
    priority_queue<int> pq;

    pq.push(3);
    pq.push(1);
    pq.push(4);
    pq.push(1);

    while (!pq.empty())
    {
        cout << pq.top() << " ";
        pq.pop();
    }

    return 0;
}

这段代码将输出:4 3 1 1。

我们发现,优先级队列会按照元素大小进行比较,默认的比较规则是该类型的“小于”运算符。在C++ STL中,小于运算符可以通过重载来实现自定义,其定义方式为bool operator< (const 该类型& a, const 该类型& b)

自定义比较

但是,当我们需要对元素多次进行比较时,如果只能使用小于运算符,就无法实现,此时我们就需要在定义队列时传入自定义比较函数。

#include <iostream>
#include <queue>
#include <string>
using namespace std;

struct Student
{
    string name;
    int age;
    int score;
};

bool cmp1(const Student& a, const Student& b)
{
    return a.age > b.age;  // 按照年龄从大到小排序
}

bool cmp2(const Student& a, const Student& b)
{
    return a.score < b.score;  // 按照分数从小到大排序
}

int main()
{
    priority_queue<Student, vector<Student>, decltype(&cmp1)> pq(cmp1);  // 按照年龄排序
    // priority_queue<Student, vector<Student>, decltype(&cmp2)> pq(cmp2);  // 按照分数排序

    pq.push(Student{"Lucy", 20, 92});
    pq.push(Student{"Alice", 18, 86});
    pq.push(Student{"Tom", 22, 80});
    pq.push(Student{"Bob", 19, 88});

    while (!pq.empty())
    {
        Student s = pq.top();
        cout << s.name << " " << s.age << " " << s.score << endl;
        pq.pop();
    }

    return 0;
}

这段代码定义了一个存储学生信息的优先级队列。在定义队列时,需要传入三个参数:元素类型、底层容器类型和比较函数类型。比较函数类型要使用decltype来推导。在本例中,分别定义了两个比较函数,一个按照年龄排序,一个按照分数排序。我们可以选择其中一个比较函数来传入队列构造函数,这样就可以实现自定义排序了。

我们可以把第15行代码注释掉,改为第16行代码,这样就可以按照分数排序。运行结果如下所示:

Lucy 20 92
Bob 19 88
Alice 18 86
Tom 22 80

结论

C++ STL中的默认优先级队列是按照元素大小(小于运算符)进行比较的,如果需要自定义比较规则,需要在定义队列时传入自定义比较函数,并在比较函数中编写自己的比较规则。通过传入不同的比较函数,我们可以实现不同的排序需求。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程