stack 是一种后进先出 ( LIFO ) 的数据结构,它对外只开放一个叫做栈顶的口,数据从栈顶入,也从栈顶出,也不允许有遍历的行为。
- 完整实现代码
概述
栈是一种运算受限的序列式容器,它的行为被限定在只能在一端进行增删操作,我们把这一端称为栈顶,相对的另一端为栈底。
栈的插入 (push()
) 操作又被称为 “入栈” ,新来的数据元素只能被插到栈顶。删除 (pop()
) 操作又称为“出栈”,出栈时栈顶的一个数据元素被删除。除此之外,栈还提供访问栈顶数据元素(top()
)的操作,获取栈大小 (size()
) 的操作,判断栈是否为空 (empty()
) 的操作。
以上所述就是 STL (在 c++98 和 c++11 中还有其它操作)中有关栈的所有操作。
栈的操作
- push()
如上图所示,栈的插入操作中,最后一个插入的元素总是置于栈顶。
- pop()
删除操作总是删掉最后被插入的数据元素。
- top()
top()
操作返回位于栈顶的数据元素。
适配器模式
手机的充电电压为 5v, 而我国家庭用电的标准电压是 220v,如何让家庭电源能给手机充电呢,我们可以引入一个电源适配器,这样 220v的家庭电压即可给手机充电,不仅如此,我们还可以引入更多不同电压的适配器以满足给各种不同电压的电器供电。而在这其中,电源适配器扮演了一个中转的角色。
在软件开发中,我们有时也会遇到类似的情况,这时我们需要引入一个和电源适配器类似的称为适配器 (adpaters)的模式,处理程序接口不兼容的情况。
实际上,STL 中的 stack 就是一个适配器, 在 STL 中它的源码如下:
template <class T, class Sequence = deque<T> >
class stack{
...
protected:
Sequence c;
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
reference top() { return c.back(); }
const_reference top() const { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_back(); }
};
...
从源码中我们看到,栈的插入、删除操作只是简单的调用的模板参数的尾插、尾删操作。
栈以某种既有的容器 (默认为deque
) 为底部结构,将其接口封装,使之符合 “后进先出” 的特性。deque
是一个双向开口的容器,以它作为栈的底部结构,将其某一端的插入和删除操作封装暴露给用户,而屏蔽掉其它操作,即可实现一个栈。 所以,严格来说,栈是一个适配器而非容器。
事实上,任何具有在某一端执行插入和删除操作的序列式容器都可以作为栈的底部结构,而这种方法的实现只需给它一个模板参数即可。
下面是以 vector
和 list
作为底部结构的 stack
:
适配器作为一种设计模式,被广泛用于软件开发中。上述的 stack
是某个类的适配器,除此之外,还有迭代器的适配器、仿函数的适配器,它们分别用于实现某些特定的功能,相关介绍请关注后序博客。
——谢谢!
参考资料
【作者:果冻 http://blog.csdn.net/jelly_9】