📜  使用堆的优先级队列 - C++ (1)

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

使用堆的优先级队列 - C++

堆是一种被广泛应用的数据结构,其中最重要的一种应用就是实现优先级队列。C++ STL库提供了一个非常灵活的优先级队列类,它使用堆数据结构来实现。本文将介绍如何使用堆的优先级队列类以及提供一些使用示例。

堆是一个完全二叉树,满足任意节点的值不小于(或不大于)其子节点的值,被称为大(或小)根堆。堆最常用的操作是插入和删除最值。

在C++中,我们可以使用priority_queue类来实现堆数据结构。这个类提供了一些操作,例如插入和删除最值,以及查询堆顶元素等。

priority_queue

priority_queue模板类定义在头文件中,它的模板参数T是存储的元素类型,比如int,char等。默认情况下,priority_queue使用std::less模板类作为比较器,也就是说生成一个大根堆。

下面的代码片段创建一个priority_queue对象,插入一些元素并弹出,可以看到元素按照从大到小的顺序弹出:

#include <iostream>
#include <queue>

using namespace std;

int main() {
  priority_queue<int> q;
  
  q.push(10);
  q.push(20);
  q.push(5);

  while (!q.empty()) {
    cout << q.top() << endl;
    q.pop();
  }

  return 0;
}

输出:

20
10
5

我们可以使用greater模板类来定义priority_queue的比较器,生成一个小根堆。下面的代码片段使用greater模板类来定义比较器,以相同的方式向队列中插入元素:

#include <iostream>
#include <queue>

using namespace std;

int main() {
  priority_queue<int, vector<int>, greater<int> > q;
  
  q.push(10);
  q.push(20);
  q.push(5);

  while (!q.empty()) {
    cout << q.top() << endl;
    q.pop();
  }

  return 0;
}

输出:

5
10
20
自定义比较器

我们还可以使用自定义的比较器来定义priority_queue。下面的代码片段定义一个结构体LessByX,其中x是一个整数成员变量。这个结构体的()运算符将使用成员变量x来比较两个元素的大小。我们创建一个priority_queue对象,并使用LessByX结构体作为比较器。

#include <iostream>
#include <queue>

using namespace std;

struct LessByX {
  bool operator()(const int& a, const int& b) const {
    return a < b;
  }
};

int main() {
  priority_queue<int, vector<int>, LessByX> q;
  
  q.push(10);
  q.push(20);
  q.push(5);

  while (!q.empty()) {
    cout << q.top() << endl;
    q.pop();
  }

  return 0;
}

输出:

20
10
5
总结

本文介绍了如何使用堆的优先级队列类priority_queue。无论是生成大根堆还是小根堆,甚至自定义比较器,都可以轻松实现。在C++中,使用堆的优先级队列类可以大大简化代码实现,提高效率。