stack_queue
- 容器适配器
- stack详解
- 栈适配器
- 栈模拟实现
- 队列详解
- 队列适配器
- queue模拟实现
容器适配器
除了顺序容器外,标准库还定义了三个顺序容器适配器:stack(栈),queue(队列),priority_queue(优先队列)。适配器是标准库中的一个通用概念。容器,迭代器和函数都有适配器。本质上一个适配器是一种机制,能使某种事物的行为看起来像另外一种事情一样。一个适配器接受一种已有的容器类型。使其行为看起来像一种不同的类型。
默认情况下,stack和queue是基于deque(双端队列)实现的,priority_queue是再vector之上实现的。
template <class T, class Container = deque<T> > class stack;
template <class T, class Container = deque<T> > class queue;
template <class T, class Container = vector<T>,class Compare = less<typename Container::value_type> > class priority_queue;
我们可以再创建一个适配器时将一个命名的顺序容器作为第二个类型参数,来重载默认的容器类型。
stack<int,vector<int>> stk;
stack<int,list<int>> stk;
queue<int,vector<int>> q;
对一个给定的适配器,可以使用哪些容器是有限制的。所有适配器都要求容器具有添加和删除元素的能力。因此,适配器不能构造再array之上。
stack只要求push_back,pop_back,back操作,可以使用除array和forward_list之外的任何容器类型来构造stack。
queue适配器要求back,push_back,front,push_front,因此它的构造可以构造于list,deque之上,但是不能用vector,因为vector没有push_front等函数,但自己模拟实现的时候,强行用vector也是可以实现的。
priority_queue除了front,push_back,pop_back操作之外,还要求随机访问能力,因此它可以再vector和deque的基础上构造,但不能用list,list不支持随机访问。
stack详解
栈适配器
stack类型定义再stack头文件中,栈所支持的操作不算太多,再之前的数据结构中模拟实现栈的时候,大部分函数已经实现。
std::stack<int> stk;//空栈stk.push(1);//压栈stk.push(2);stk.push(3);stk.push(4);while (!stk.empty()/*判断栈是否为空*/){std::cout << stk.top() << ' ';//输出栈顶元素stk.pop();//出栈}
每个容器适配器都基于底层容器类型的操作定义了自己的特殊操作,我们只可以使用适配器操作,而不能使用底层容器类型的操作。
栈模拟实现
namespace HaiFan
{template <class T, class Container = deque<T> > class stack{public:void push(const T& x){_con.push_back(x);}T top(){return _con.back();}bool empty(){return _con.empty();}void pop(){_con.pop_back();}size_t size(){return _con.size();}void swap(stack<T>& it){_con.swap(it._con);}//swap函数交换的是容器对象,而不是it本身,所以再模拟实现按的时候要注意一下,否则会出现类型不匹配的报错。private:Container _con;};
}
队列详解
队列适配器
queue和priority_queue适配器定义再queue头文件中。
queue
priority_queue
标准库queue使用一种先进先出的存储和访问策略。进入队列的对象被放置到队尾,而离开队列的对象则从队首删除。
priority_queue允许我们为队列中的元素建立优先级。新加入的元素会排在所有优先级比他低的已有元素之前。
queue的用法很简单,empty判空,size队列大小,front队首元素,back队尾元素,push入队,pop出队。
优先队列其实是一个堆
priority_queue<int, vector<int>, greater<int>> q;//greater小根堆,less大根堆q.push(1);q.push(-1);q.push(100);q.push(120);q.push(10);while (q.size()){cout << q.top() << ' ';q.pop();}
queue模拟实现
#pragma once#include <deque>namespace HaiFan
{template<class T,class Container = deque<T>>class queue{public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}T front(){return _con.front();}T back(){return _con.back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}private:Container _con;};
}