📌  相关文章
📜  C++中的优先级对队列,按第一个和第二个元素排序(1)

📅  最后修改于: 2023-12-03 15:29:54.214000             🧑  作者: Mango

C++中的优先级队列

优先级队列(Priority Queue)是一种特殊的队列,它允许我们在O(log n)时间内获取并删除队列中的最大值或最小值。C++ STL中的优先级队列基于堆实现,可以用来解决许多贪心算法问题。

基本用法

C++ STL中的优先级队列定义如下:

template <class T, class Container = vector<T>,
          class Compare = less<typename Container::value_type> > class priority_queue;

其中,T是元素类型,Container是内部容器类型,默认使用vector,Compare是元素比较函数类型,默认使用less。

我们可以通过以下代码创建一个最大堆:

#include <queue>
using namespace std;

priority_queue<int> pq; // 默认是最大堆

优先级队列支持push、pop、top等操作,用法与普通队列类似。下面是一个示例,实现了一个求中位数的程序:

#include <queue>
using namespace std;

priority_queue<int> lo;                             // 最大堆
priority_queue<int, vector<int>, greater<int>> hi;  // 最小堆

void addNum(int num) {
    lo.push(num);
    hi.push(lo.top());
    lo.pop();

    if (lo.size() < hi.size()) {
        lo.push(hi.top());
        hi.pop();
    }
}

double findMedian() {
    if (lo.size() > hi.size()) {
        return (double)lo.top();
    } else {
        return (double)(lo.top() + hi.top()) / 2;
    }
}
自定义比较函数

默认情况下,优先级队列会按照元素类型的小于运算符(operator<)进行比较。如果我们需要按照自定义的方式排序,可以自己编写比较函数。

比如,我们希望将优先级队列按照元素类型的第一个元素从小到大排序,如果第一个元素相同,则按照第二个元素从小到大排序。可以这样写:

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

struct MyCompare {
    bool operator() (const vector<int>& a, const vector<int>& b) {
        if (a[0] != b[0]) {
            return a[0] > b[0]; // 按第一个元素从小到大排序
        } else {
            return a[1] > b[1]; // 如果第一个元素相同,按第二个元素从小到大排序
        }
    }
};

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

    pq.push({1, 3});
    pq.push({2, 2});
    pq.push({3, 1});

    while (!pq.empty()) {
        cout << pq.top()[0] << ", " << pq.top()[1] << endl;
        pq.pop();
    }

    return 0;
}

输出结果为:

1, 3
2, 2
3, 1

可以看到,优先级队列按照我们自定义的方式排序了。自定义比较函数时,需要注意以下两点:

  1. 比较函数必须是一个类,或是一个结构体。
  2. 比较函数需要重载小于运算符(operator<)或使用仿函数的方式实现,具体实现方法可以参考示例代码。
总结

本文介绍了C++ STL中的优先级队列的基本用法和自定义排序方式的方法。优先级队列是应用广泛的数据结构之一,具有广泛的应用场景。当然,除了STL中提供的优先级队列,我们也可以自己实现堆来实现优先级队列,这里就不再赘述了。