📜  C++ STL-priority_queue(1)

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

C++ STL-priority_queue

概述

priority_queue是C++ STL(标准模板库)中的一个容器适配器,它提供了一种高效的数据结构:堆,用于存储和管理元素。堆按照某一指定的优先级排序,常常被用作贪心算法和图算法的辅助数据结构。

特点
  • 在添加元素时,priority_queue会自动将元素加入堆中,并将其放置在恰当的位置。
  • 在删除元素时,priority_queue会将堆顶元素移除,并重新排列堆。
  • 默认情况下,priority_queue按照元素类型的小于操作符(<)排序,可以通过自定义比较函数来指定堆的排序方式。
使用示例
#include <iostream>
#include <queue>
using namespace std;

int main() {
    // 创建一个存储整型数值的优先级队列,默认按照从大到小排序
    priority_queue<int> pq;

    pq.push(10);
    pq.push(30);
    pq.push(20);

    // 输出堆顶元素(最大值)
    cout << pq.top() << endl;

    pq.pop(); // 弹出堆顶元素(最大值)
    cout << pq.top() << endl;

    return 0;
}

输出

30
20
默认排序

默认情况下,priority_queue会按照元素类型的小于操作符(<)对元素进行排序,例如对于整型数据,会按照从大到小的顺序进行排序,因此堆顶元素是最大值。对于其他数据类型,如字符串或自定义对象,需要定义小于操作符或自定义比较函数来指定堆的排序方式。下面是一个自定义对象的示例:

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

struct Person {
    string name;
    int age;
    bool operator<(const Person& other) const {
        return age < other.age; // 按照年龄进行排序
    }
};

int main() {
    // 创建一个存储结构体Person的优先级队列
    priority_queue<Person> pq;

    pq.push({"Alice", 20});
    pq.push({"Bob", 30});
    pq.push({"Charlie", 25});

    // 输出堆顶元素(年龄最大的人)
    cout << pq.top().name << endl; // 输出Bob

    pq.pop(); // 弹出堆顶元素(年龄最大的人)
    cout << pq.top().name << endl; // 输出Charlie

    return 0;
}
自定义比较函数

可以通过自定义比较函数来指定堆的排序方式,比较函数需要返回一个bool值,表示两个元素的优先级大小。下面是一个按照字符串长度排序的示例:

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

bool cmp(const string& s1, const string& s2) {
    return s1.length() < s2.length(); // 按照字符串长度进行排序
}

int main() {
    // 创建一个存储字符串的优先级队列,按照字符串长度排序
    priority_queue<string, vector<string>, decltype(&cmp)> pq(&cmp);

    pq.push("Alice");
    pq.push("Bob");
    pq.push("Charlie");

    // 输出堆顶元素(长度最大的字符串)
    cout << pq.top() << endl; // 输出Charlie

    pq.pop(); // 弹出堆顶元素(长度最大的字符串)
    cout << pq.top() << endl; // 输出Alice

    return 0;
}
注意事项
  • priority_queue不支持遍历操作,只能访问堆顶元素。
  • priority_queue是一种动态数据结构,不支持随机访问,因此时间复杂度较高,最好避免使用查找操作。
  • 使用自定义比较函数时,需要使用decltype关键字来定义堆的比较类型。如果使用lambda表达式作为比较函数,也可以使用auto来定义比较类型。