容器适配器
- 可以用某种顺序容器来实现(让已有的顺序容器以栈/队列的方式工作)
- 1) stack: 头文件
<stack>
- 栈 – 后进先出
- 2) queue: 头文件
<queue>
- 队列 – 先进先出
- 3) priority_queue: 头文件
<queue>
- 优先级队列 – 最高优先级元素总是第一个出列
- 都有3个成员函数:
push
: 添加一个元素top
: 返回栈顶部或队头元素的引用pop
: 删除一个元素
- 容器适配器上没有迭代器 ->STL中各种排序,查找,,变序等算法都不适合容器适配器
stack
- stack是后进先出的数据结构
- 只能插入,删除,访问栈顶的元素
- 可用 vector, list, deque来实现
- 缺省情况下, 用deque实现
- 用 vector和deque实现, 比用list实现性能好
template<class T, class Cont = deque<T> >
class stack {
…
};
- stack 中主要的三个成员函数:
void push(const T & x);
将x压入栈顶
void pop();
弹出(即删除)栈顶元素T & top();
返回栈顶元素的引用,通过该函数, 可以读取栈顶元素的值, 也可以修改栈顶元素
queue
- 和stack 基本类似, 可以用 list和deque实现
- 缺省情况下用deque实现
template<class T, class Cont = deque<T> >
class queue {
……
};
- 同样也有
push, pop, top
函数
- push发生在队尾
- pop, top发生在队头, 先进先出
priority_queue
- 和 queue类似, 可以用vector和deque实现
- 缺省情况下用vector实现
- priority_queue 通常用堆排序技术实现, 保证最大的元素总是在最前面
- 执行pop操作时, 删除的是最大的元素
- 执行top操作时, 返回的是最大元素的引用
- 默认的元素比较器是 less
基本数据类型的优先级设置
此处指的基本数据类型就是 int
型,double
型,char
型等可以直接使用的数据类型,优先队列对他们的优先级设置一般是数字大的优先级高,因此队首元素就是优先队列内元素最大的那个(如果是 char 型,则是字典序最大的)。
//下面两种优先队列的定义是等价的
priority_queue<int> q;
priority_queue<int, vector<int>, less<int> >; //后面有一个空格
其中第二个参数( vector ),是来承载底层数据结构堆的容器,第三个参数( less ),则是一个比较类,less 表示数字大的优先级高,而 greater 表示数字小的优先级高。
如果想让优先队列总是把最小的元素放在队首,只需进行如下的定义:
priority_queue<int, vector<int>, greater<int> >q;
示例代码:
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<double> priorities;
//priority_queue<double, vector<double>, greater<double> > priorities;
priorities.push(3.2);
priorities.push(9.8);
priorities.push(5.4);
while (!priorities.empty()) {
cout << priorities.top() << " ";
priorities.pop();
}
cout << endl;
}
输出结果:
9.8 5.4 3.2
若定义队列为注释中的形式,则输出结果:
3.2 5.4 9.8
结论:假设比较函数为op
,priority_queue保证对于队头元素和队列中其余的元素有关系op(x, y) == false
#include <iostream>
#include <queue>
using namespace std;
struct cmp {
bool operator() (int a, int b) {
return (a % 10) > (b % 10);
}
};
int main() {
// priority_queue<double> priorities;
priority_queue<int, vector<int>, cmp > priorities;
priorities.push(30);
priorities.push(29);
priorities.push(12);
while (!priorities.empty()) {
cout << priorities.top() << " ";
priorities.pop();
}
cout << endl;
}
结构体的优先级设置
方式一:重载运算符 <
可以在结构体内部重载 <
,改变小于号的功能(例如把它重载为大于号)
struct student{
int grade;
string name;
//重载运算符,grade 值高的优先级大
friend operator < (student s1, student s2) {
return s1.grade < s2.grade;
}
};
void test2(){
priority_queue<student> q;
student s1,s2,s3;
s1.grade = 90;
s1.name = "Tom";
s2.grade = 80;
s2.name = "Jerry";
s3.grade = 100;
s3.name = "Kevin";
q.push(s1);
q.push(s2);
q.push(s3);
while(!q.empty()){
cout << q.top().name << ":" << q.top().grade << endl;
q.pop();
}
}
/*
结果:
Kevin:100
Tom:90
Jerry:80
*/
方式二:把重载的函数写在结构体外面
将比较函数写在结构体外面,作为参数传给优先队列。
struct fruit {
string name;
int price;
};
struct cmp{
// "<" 表示 price 大的优先级高
bool operator() (fruit f1, fruit f2){
return f1.price < f2.price;
}
};
void test3() {
priority_queue< fruit, vector<fruit>, cmp > q;
fruit f1,f2,f3;
f1.name = "apple";
f1.price = 5;
f2.name = "banana";
f2.price = 6;
f3.name = "pear";
f3.price = 7;
q.push(f1);
q.push(f2);
q.push(f3);
while(!q.empty()){
cout<<q.top().name<<":"<<q.top().price<<endl;
q.pop();
}
}
/*
结果:
pear:7
banana:6
apple:5
*/
部分转载自:https://blog.csdn.net/pzhu_cg_csdn/article/details/79166858