栈(stack)和队列(queue)均可以存放各种类型的元素,但是在标准库(STL)中并没有将二者划为容器领域,而是将其称为容器适配器,它们将其它容器进行包装使用,也就是通过容器中的函数来实现栈和队列的功能。
1、栈(stack)
(1)栈适合用于有元素后进先出(LIFO)的场景,即元素的删除(出栈)和插入(压栈)只能从容器的一端进行。在内存中存储方式是先存高地址然后再往低地址扩展。
(2)栈的模拟实现
栈的基本功能:
namespace room {
//缺省变量代表默认使用vector<>容器
template<class T,class Container = vector<T>>
class stack {
public:
//压栈
void push(const T& x) {
//尾插尾删不用挪数据
_con.push_back(x);
}
//出栈
void pop() {
_con.pop_back();
}
//判断是否为空栈
bool empty() const{
return _con.empty();
}
//栈顶元素
T& top() {
return _con.back();
}
//栈中元素个数
size_t size() const{//const表示成员变量不能改变
return _con.size();
}
private:
//栈所使用的容器
Container _con;
};
}
2、队列
(1)队列适合先进先出(FIFO)场景,即元素的插入(入队列)和删除(出队列)分别从容器的两端进行插入和删除数据。队列是通过链表实现的,插入数据过程中new创建的空间是随机的,内存的位置先后也是随机的,只有同时new出的多个同类型的空间地址才是有序的,并且按照低地址往高地址的顺序。
(2)队列的模拟实现:
队列的基本功能:
namespace room1 {
//queue接口中存在尾插头删,用vector效率低
template<class T>
class queue {
public:
//空队列判断
bool empty() const{
return _con.empty();
}
//队列元素个数
size_t size() const{
return _con.size();
}
//对头元素
const T& front()const {
return _con.front();
}
//队尾元素
const T& back() const{
return _con.back();
}
//入队
void push(const T& x) {
_con.push_back(x);
}
//出队
void pop(){
_con.pop_front();
}
private:
//list容器,设计到头删,用顺序表会涉及到挪数据,效率低
list<T> _con;
};