一、STL - stack
1.1 stack 的介绍
文档介绍:stack - C++ Reference (cplusplus.com)
// T: 容器中存储的元素的类型
template <class T, class Container = deque<T> > class stack;
-
stack 是一种「容器适配器」(container adapter),专门用在具有 LIFO (后进先出) 操作的上下文环境中,其中元素仅从容器的一端插入和提取。
-
stack 是作为容器适配器被实现的,「容器适配器」即是「对特定容器类封装」作为其底层的容器,并提供一组特定的成员函数来访问其元素,元素从特定容器的尾部(即栈顶)被压入和弹出,这被称为堆栈的顶部。
-
stack 的底层容器可以是任何标准容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:
-
empty:判空操作
-
size:获取有效元素个数
-
back:获取尾部元素操作
-
push_back:尾部插入元素操作
-
pop_back:尾部删除元素操作
-
-
标准容器类 vector、deque、list 均符合这些要求,默认情况下,如果没有为 stack 指定特定的底层容器类,则使用标准容器双端队列 deque。
容器适配器/配接器:不是直接实现的,封装其他容器,包装转换实现出来的。
1.2 stack 的使用
stack 没有迭代器,有了迭代器就可以随意访问元素了,不能保证「后进先出」的性质了。
成员函数 | 接口说明 |
---|---|
stack() | 构造一个堆栈容器适配器对象,构造空的栈。 |
empty | 检查 stack 是否为空 |
size | 返回 stack 中有有效元素的个数 |
top | 返回栈顶元素的引用 |
push | 压栈,将一个元素压入 stack 中 |
pop | 出栈,将 stack 尾部元素弹出 |
swap(C++11) | 交换两个容器的内容(该成员函数调用非成员函数 std::swap 来交换底层容器) |
👉 Example:
void test_stack1()
{
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
// 遍历堆栈中的元素
while (!st.empty())
{
cout << st.top() << " ";
st.pop();
}
}
1.3 stack 的模拟实现
不需要写构造函数,因为在默认构造函数的初始化列表阶段,自定义类型成员 _con 会自动调用它的默认构造函数
namespace winter
{
/*
* T: 堆栈中存储的数据的类型
* Container: 适配堆栈的容器类型,默认为deque
*/
template<class T, class Container = std::deque<T>>
class stack
{
// stack 是一个 Container 适配(封装转换)出来的
// 把 Contariner 的尾部认为是栈顶
public:
bool empty() // 判空
{
return _con.empty();
}
size_t size() const // 获取有效元素的个数
{
return _con.size();
}
const T& top() const // 返回栈顶元素的引用
{
return _con.back();
}
void push(const T& val) // 压栈,尾插
{
_con.push_back(val);
// 大家可能会有疑问,如果 _con 没有 push_back 接口怎么办呢?
// 没有就报错呗,说明你不能适配我
}
void pop() // 出栈,尾删
{
_con.pop_back();
}
// C++11
void swap(stack<T, Container>& st) // 交换两个容器的内容
{
// 注意:底层调用的是非成员函数 std::swap 来交换底层容器
std::swap(_con, st._con);
}
private:
Container _con; // 适配的容器
};
// 测试
void test1()
{
//stack<int, std::vector<int>> st; // 用vector适配
//stack<int, std::list<int>> st; // 用list适配
stack<int> st; // 默认用deque适配
st.push(1);
st.push(2);
st.push(3);
// 遍历堆栈中的元素
while (!st.empty())
{
cout << st.top() << " ";
st.pop();
}
cout << endl;
}
}
二、STL - queue 的介绍
2.1 queue 的介绍
文档介绍:queue - C++ Reference (cplusplus.com)
// T: 容器中存储的元素的类型
template <class T, class Container = deque<T> > class queue;
-
队列是一种「容器适配器」(container adapter),专门用于在 FIFO (先进先出) 操作的上下文环境中,其中从容器一端插入元素,另一端提取元素。
-
队列作为容器适配器实现,「容器适配器」即「对特定容器类封装」作为其底层容器类,queue 提供一组特定的成员函数来访问其元素。元素从队尾入队列,从队头出队列。
-
底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操作:
-
empty:检测队列是否为空
-
size:返回队列中有效元素的个数
-
front:返回队头元素的引用
-
back:返回队尾元素的引用
-
push_back:在队列尾部入队列
-
pop_front:在队列头部出队列
-
-
标准容器类双端队列 deque 和带头双向循环链表 list 满足了这些要求。默认情况下,如果没有为 queue 实例化指定容器类,则使用标准容器双端队列 deque。
2.2 queue 的使用
注意:queue 没有迭代器,有了迭代器就可以随意访问元素了,不能保证「先进先出」的性质了。
成员函数 | 接口说明 |
---|---|
queue() | 构造一个队列容器适配器对象。构造空的队列 |
empty | 检测队列是否为空 |
size | 返回队列中有效元素的个数 |
front | 返回队头元素的引用 |
back | 返回队尾元素的引用 |
push | 入队,将一个元素从队尾入队列 |
pop | 出队,将队头元素出队列 |
swap (C++11) | 交换两个容器的内容(该成员函数调用非成员函数 std::swap 来交换底层容器) |
👉 Example:
void test_queue1()
{
queue<int> q;
q.push(1);
q.push(2);
q.push(3);
// 遍历队列中的元素
while (!q.empty())
{
cout << q.front() << " ";
q.pop();
}
}
2.3 queue 的模拟实现
不需要写构造函数,因为在默认构造函数的初始化列表阶段,自定义类型成员 _con 会自动调用它的默认构造函数
namespace winter
{
/*
* T: 队列中存储的数据的类型
* Container: 适配队列的容器类型,默认为deque
*/
template<class T, class Container = std::deque<T>>
class queue
{
public:
bool empty() // 判空