STL在C++中起到非常重要的作用,最大的好处就是将常见的数据结构进行了封装,使得我们不需要从底层一步步去实现,使用起来非常方便。C++知识小屋🏠的STL系列旨在将常见STL库的常见函数进行小结,以函数+示例+结果展示的方式作为文章的整体结构。希望能够在用到这些库的时候能够快速上手,熟练地使用它们来解决一些常见的问题。
什么是优先队列(priority_queue)?
- 对于普通的队列,其排列的顺序符合FIFO原则,即先进去的先出来。但是在实际应用的时候,有时候我们想要实现一些别的输出规则,比如大的先出,小的后出。换句话说就是我们想要对队列内部进行排序。而优先队列就能实现这个功能。
- 要使用优先队列,首先得在程序前面定义其包含的库:
#include <queue>
优先队列的定义,输入,输出
-
由于优先队列能够按照某种方式进行排序,所以在定义的时候就要声明我们需要按照什么方式进行排序。下面展示了int类型的优先队列的三种定义方法:
1.priority_queue<int> A; //先输出大的,后输出小的
- 这种方法直接指定优先队列的类型,是比较简便的创建方法,该方法等同于下面的方法二,即值较大的元素在队列的前面(即top,会先被pop输出出来),值小的放在后面。 (降序)
2.
priority_queue<int,vector<int>,less<int> > B; //先输出大的,后输出小的
- 这种方法为优先队列的原始定义方法,包含了三个参数(注意最后两个’’>"中间要用空格隔开,否则系统会默认为“>>”符号):
- 第一个参数为类型
- 第二个参数为vector<“类型”>,这个vector是默认的,记住就好
- 第三个参数是排序方式,less表示小的在队列的底部,大的在队列的头部(先被输出)(降序)
3.
priority_queue<int,vector<int>,greater<int> >C; //先输出大的,后输出小的
- 与上面的方法一样,有三个参数,其中greater表示小的先被输出,大的后被输出(升序)
-
优先队列的输入元素使用push函数即可
-
优先队列的输出与普通的队列一样,通过top()函数获取顶部的元素,再通过pop()函数弹出顶部的元素。
程序示例
- 下面的程序展示了A,B为降序的方式,C为升序的方式。这个记住就好啦。
#include <iostream>
#include <queue>
using namespace std;
int main(){
//构造对象A (后面的两个'>'中间一定要有空格,否则会报错)
priority_queue<int> A; //先输出大的,后输出小的
priority_queue<int,vector<int>,less<int> > B; //先输出大的,后输出小的
priority_queue<int,vector<int>,greater<int> >C; //先输出大的,后输出小的
//输入元素
A.push(1);
A.push(3);
A.push(2);
B.push(1);
B.push(3);
B.push(2);
C.push(1);
C.push(3);
C.push(2);
cout << "A: " ;
while(!A.empty()){
cout << A.top() << " ";
A.pop();
}
cout << endl << "B: ";
while(!B.empty()){
cout << B.top()<< " ";
B.pop();
}
cout << endl << "C: ";
while(!C.empty()){
cout << C.top() << " ";
C.pop();
}
return 0;
}
优先队列的自定义排序方法
- 在实际应用中,往往优先队列的类型是我们自定义的类,这时候就需要我们自己定义排序方式了。下面提供了两种排序方式:
-
第一种方法:在类里面重载"<"符号,然后定义优先队列的时候直接声明类名即可。
- 比如下面我们在Point类里面重载了"<"符号(注意要是const类型),然后在定义的时候直接定义即可:
priority_queue<Point> A;
这样子就会按照重载函数里面的规则进行排序
- 比如下面我们在Point类里面重载了"<"符号(注意要是const类型),然后在定义的时候直接定义即可:
-
第二种方法:在类外面构建cmp结构体,在结构体里面重载()符号为自定义排序规则,然后定义的时候需要声明排序规则为cmp,如
priority_queue<Point,vector<Point>,cmp> B
.
程序示例
- 下面展示了两种自定义排序方法的示例,通过结果可以看到通过类内重载“<”的A最后的排序结果为:先输出x比较小的,载输出y比较小的
- 而通过cmp方式排序的B,先输出x比较da的,再输出y比较大的。
#include <iostream>
#include <queue>
using namespace std;
class Point{
public:
int x,y;
Point(int _x = 0,int _y = 0){
x = _x;
y = _y;
}
//自定义排序方法一:重载"<" 运算符,注意要使用const的方法才行,否则会报错
bool operator < (const Point & A) const{
if(x != A.x){
return x > A.x; //先输出x小的再输出y小的
}
else{
return y > A.y;
}
}
friend ostream & operator << (ostream & o,const Point &A){
o << "x = " << A.x << " , y = " << A.y << endl;
return o;
}
};
//自定义排序方法二:在外面定义
struct cmp{
bool operator()(const Point & A,const Point & B){
if(A.x != B.x){
return A.x < B.x; //先输出x大的,再输出y大的
}
else{
return A.y < B.y;
}
}
};
int main(){
priority_queue<Point> A; //采用A内部重载的"<"符号的排序方式
priority_queue<Point,vector<Point>,cmp> B; //采用cmp方法进行排序
A.push(Point(2,1));
A.push(Point(1,1));
A.push(Point(1,2));
B.push(Point(2,1));
B.push(Point(1,1));
B.push(Point(1,2));
cout << "A: " << endl; //输出A的元素
while(!A.empty()){
cout << A.top() ;
A.pop();
}
cout << "B: " << endl; //输出B的元素
while(!B.empty()){
cout << B.top() ;
B.pop();
}
return 0;
}