上次我们简单了解了一下容器适配器与deque的结构和优劣, 这次我们就直接进入几种容器适配器的学习, 首先我们来看stack(栈).
一. stack的认识
这是C++官方对stack的定义, 我们可以看到他是有第二个参数的, 这个参数可以理解为底层实现的容器, 在创建stack对象的时候我们可以传入不同的容器创建不同底层结构的stack
不过一般如果没有特殊需求的话, 用默认的就挺香的.
二. stack的接口使用
相信大家对栈都有一定的了解吧, 后进先出的数据结构
容器适配器的接口都提供的比较少, 这里给出一个表格
Operator | 接口说明 |
---|---|
stack() | 构造一个空的栈 |
push() | 入栈 (尾插) |
pop() | 出栈(尾删) |
top() | 获取栈顶元素 (数组的尾元素) |
size() | 获取有效元素个数 |
empty() | 判空 |
这里我们就不测试了, 直接给出经常使用的代码 :
void test() {
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
st.push(4);
st.push(5);
//不为空的话打印栈顶元素, 然后出栈, 继续循环
while (!st.empty()) {
cout << st.top() << " ";
st.pop();
}
cout << endl;
}
运行结果如下:
三. stack的实现
1. 不包含第二参数的实现
这里实现非常简单, 基本都是一两句代码, 所以不再一一解释
核心就是 : 尾插和尾删
template <class T>
class Stack {
public:
//构造函数不用写,
//因为自动调用vector的构造函数构造一个vector
//入栈
void push(const T& val) {
_v.push_back(val);
}
//出栈
void pop() {
_v.pop_back();
}
//获取栈顶元素
T& top() {
return _v.back();
}
//判空
bool empty() {
return _v.empty();
}
//size
size_t size() {
return _v.size();
}
private:
vector<T> _v;
};
下面给出测试代码:
void test() {
Stack<int> st;
st.push(1);
st.push(2);
st.push(3);
st.push(5);
st.push(4);
while (!st.empty()) {
cout << st.top() << " ";
st.pop();
}
cout << endl;
}
运行结果如下:
结果正确..注意上面插入顺序~
2. 带有第二参数的实现
其实就是多加一个泛型参数, 在声明成员变量时, 类型换成这个泛型类型即可, 主要是通过对比感受一下这种实现方法
template <class T, class Container>
class Stack {
public:
//构造函数不用写
//入栈
void push(const T& val) {
_v.push_back(val);
}
//出栈
void pop() {
_v.pop_back();
}
//获取栈顶元素
T& top() {
return _v.back();
}
//判空
bool empty() {
return _v.empty();
}
//size
size_t size() {
return _v.size();
}
private:
Container _v;
};
下面给出测试代码 :
void test2() {
//传入底层容器, 创建不同结构的stack
Stack<int, vector<int>> st;
Stack<int, list<int>> st2;
st.push(1);
st.push(2);
st.push(3);
st.push(4);
st2.push(1);
st2.push(2);
st2.push(3);
st2.push(4);
while (!st.empty()) {
cout << st.top() << " ";
st.pop();
}
cout << endl;
while (!st2.empty()) {
cout << st2.top() << " ";
st2.pop();
}
cout << endl;
}
运行结果如下:
OK, stack的接口使用和实现我们就聊到这