1.对容器适配器的理解
C++提供了三种容器适配器(container adapter):stack,queue和priority_queue。
stack和queue基于deque实现,priority_queue基于vector实现。
本质上,适配器是使一事物的行为类似于另一类事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。
举个简单的例子,我们手机充电的时候需要电源适配器来把220v的交流电转换成较低电压的直流电以供手机充电使用,220v的电压太高了,我们不需要那么高的电压,而且高电压还有可能产生其他很多不良后果。
基础的容器类型就相当于那220v的电压,经过适配器转换后才成为了我们需要的低电压(stack,queue,priority_queue)。你完全可以在deque上按照stack的方式工作,但是deque太强大了,它提供了远超过stack操作(empty, size, pop, top, push)所需的各种接口,你可以小心翼翼地在deque上只使用那几种操作来模拟一个栈,但是你很有可能一失误来个push_front()之类的操作,你小心翼翼模拟的栈就毁了。所以,我们需要适配器来做一下转换,只保留基础类型提供的接口中的一部分,保留的这部分操作对于你所需要的数据结构来说已经足够了。
2.三种容器适配器提供的操作
stack 先入后出
stack<int> s;
stack< int, vector<int> > stk; //覆盖基础容器类型,使用vector实现stk
s.empty(); //判断stack是否为空,为空返回true,否则返回false
s.size(); //返回stack中元素的个数
s.pop(); //删除栈顶元素,但不返回其值
s.top(); //返回栈顶元素的值,但不删除此元素
s.push(item); //在栈顶压入新元素item
queue和priority_queue 先入先出
queue<int> q; //priority_queue<int> q;
q.empty(); //判断队列是否为空
q.size(); //返回队列长度
q.push(item); //对于queue,在队尾压入一个新元素
//对于priority_queue,在基于优先级的适当位置插入新元素
q.pop(); //删除队列首部的元素
//queue only:
q.front(); //返回队首元素的值,但不删除该元素
q.back(); //返回队尾元素的值,但不删除该元素
//priority_queue only:
q.top(); //返回具有最高优先级的元素值,但不删除该元素
3.priority_queue(优先队列)
priority_queue和不同queue的就在于可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队,优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的,并且优先队列默认是大根堆实现的(大根堆中,父节点的值大于子节点的值)用大根堆实现的优先队列在执行pop指令时,会将其中的排好序的数据按由大到小的顺序输出。
操作函数和队列基本操作相同:
- top 访问队头元素
- empty 队列是否为空
- size 返回队列内元素个数
- push 插入元素到队尾 (并排序)
- emplace 原地构造一个元素并插入队列
- pop 弹出队头元素
- swap 交换内容
优先队列的定义方式:priority_queue<Type, Container, Functional>
- Type 就是数据类型;
- Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector);
- Functional 就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆
优先队列的模版参数:
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> > class priority_queue;
其中第三个参数表示比较方法,是一个类的形式,如果用户要自定义该方法,应该写成下面的形式:
class Cmp {
public:
bool operator()(const Node &a, const Node &b) {
return a.size == b.size ? a.price > b.price : a.size < b.size;
}
};
priority_queue<Node, vector<Node>, Cmp> priorityQueue;
声明语句:
priority_queue <int, vector<int>, greater<int>> q;//小根堆
priority_queue <int, vector<int>, less<int>> q;//大根堆 默认
//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。
//其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)