目录
1.1栈
1.2栈的使用
1.3容器适配器
1.4栈模拟实现
2.1 queue
2.2queue的使用
2.3queue的模拟实现
1.栈
1. stack
是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行
元素的插入与提取操作。
2. stack
是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定
的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部
(
即栈顶
)
被压入和弹出。
3. stack
的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下
操作:
empty
:判空操作
back
:获取尾部元素操作
push_back
:尾部插入元素操作
pop_back
:尾部删除元素操作
4.
标准容器
vector
、
deque
、
list
均符合这些需求,默认情况下,如果没有为
stack
指定特定的底层容器,
默认情况下使用
deque
。
1.2栈的使用
bool empty() //栈是否为空
void pop() //从栈顶删除元素(栈不能为空)
void push() //在栈顶插入一个新的元素
int size() //栈的数据量
T & top() //返回栈顶部的引用(栈不能为空)
stackstk;
stk.push(1);
stk.push(2);
stk.push(3);
while (!stk.empty()) {
cout << stk.top() << " ";
stk.pop();
}
1.3容器适配器
bool empty() //栈是否为空
void pop() //从栈顶删除元素(栈不能为空)
void push() //在栈顶插入一个新的元素
int size() //栈的数据量
T & top() //返回栈顶部的引用(栈不能为空)
stackstk; stk.push(1); stk.push(2); stk.push(3); while (!stk.empty()) { cout << stk.top() << " "; stk.pop(); }
1.3容器适配器
什么是容器适配器?
适配器是一种设计模式( 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总 结) ,这种模式是将一个类的接口转换成客户希望的另外一个接口
STL中stack和queue的底层结构
虽然 stack 和 queue 中也可以存放元素,但在 STL 中并没有将其划分在容器的行列,而是将其称为容器适配器 ,这是因为stack 和队列只是对其他容器的接口进行了包装, STL 中 stack 和 queue 默认使用 deque ,比如:
1.4栈模拟实现
template
class stack {
public:
void push(const T& x) {
_con.push_back(x);
}
void pop() {
_con.pop_back();
}
size_t size() {
return _con.size();
}
T& top() {
return _con.back();
}
bool empty() {
return _con.empty();
}
private:
Container _con;
};
templateclass stack { public: void push(const T& x) { _con.push_back(x); } void pop() { _con.pop_back(); } size_t size() { return _con.size(); } T& top() { return _con.back(); } bool empty() { return _con.empty(); } private: Container _con; };
测试代码:
void Test_stack() {
stack>stk;
stk.push(1);
stk.push(2);
stk.push(3);
while (!stk.empty()) {
cout << stk.top() << " ";
stk.pop();
}
}
当然我们也可以使用list做为容器适配器
void Test_stack() {
stack>stk;
stk.push(1);
stk.push(2);
stk.push(3);
while (!stk.empty()) {
cout << stk.top() << " ";
stk.pop();
}
}
2. queue
1.
队列是一种容器适配器,专门用于在
FIFO
上下文
(
先进先出
)
中操作,其中从容器一端插入元素,另一端
提取元素。
2.
队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,
queue
提供一组特定的
成员函数来访问其元素。元素从队尾入队列,从队头出队列。
3.
底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类。该底层容器应至少支持以下操
作
:
empty
:检测队列是否为空
size
:返回队列中有效元素的个数
front
:返回队头元素的引用
back
:返回队尾元素的引用
push_back
:在队列尾部入队列
pop_front
:在队列头部出队列
4.
标准容器类
deque
和
list
满足了这些要求。默认情况下,如果没有为
queue
实例化指定容器类,则使用标 准容器deque
。
2.1queue的使用
#include
#include
using namespace std;
int main() {
queueq;
q.push(1);
q.push(2);
q.push(3);
while (!q.empty()) {
cout << q.front() << " ";
q.pop();
}
return 0;
}
2.3queue的模拟实现
template
class queue {
public:
bool empty() {
return _con.empty();
}
bool size() {
return _con.size();
}
void push(const T&val) {
_con.push_back(val);
}
void pop() {
_con.pop_front();
}
T& front() {
return _con.front();
}
T& back() {
return _con.back();
}
private:
Container _con;
};
#include#include using namespace std; int main() { queue q; q.push(1); q.push(2); q.push(3); while (!q.empty()) { cout << q.front() << " "; q.pop(); } return 0; }
2.3queue的模拟实现
template
class queue {
public:
bool empty() {
return _con.empty();
}
bool size() {
return _con.size();
}
void push(const T&val) {
_con.push_back(val);
}
void pop() {
_con.pop_front();
}
T& front() {
return _con.front();
}
T& back() {
return _con.back();
}
private:
Container _con;
};
templateclass queue { public: bool empty() { return _con.empty(); } bool size() { return _con.size(); } void push(const T&val) { _con.push_back(val); } void pop() { _con.pop_front(); } T& front() { return _con.front(); } T& back() { return _con.back(); } private: Container _con; };
测试代码:
void test_queue() {
queue>q;
q.push(1);
q.push(2);
q.push(3);
while (!q.empty()) {
cout << q.front() << " ";
q.pop();
}
}
注意:queue的容器适配器不能使用vector因为vector没有提供pop_front.
最后为什么STL中会选择deque作为stack和queue底层的默认容器?
stack 是一种后进先出的特殊线性数据结构,因此只要具有 push_back() 和 pop_back() 操作的线性结构,都可 以作为 stack 的底层容器,比如 vector 和 list 都可以; queue 是先进先出的特殊线性数据结构,只要具有 push_back 和 pop_front 操作的线性结构,都可以作为 queue 的底层容器,比如 list 。但是 STL 中对 stack 和 queue 默认选择 deque 作为其底层容器,主要是因为: 1. stack 和 queue 不需要遍历 ( 因此 stack 和 queue 没有迭代器 ) ,只需要在固定的一端或者两端进行操作。 2. 在 stack 中元素增长时, deque 比 vector 的效率高 ( 扩容时不需要搬移大量数据 ) ; queue 中的元素增长 时, deque 不仅效率高,而且内存使用率高。 结合了 deque 的优点,而完美的避开了其缺陷。



