栈基础知识
栈(stack)是一种限制插入和删除只能在一端进行的线性表,允许插入删除的一端称为栈顶,另一端称为栈底。栈的基本操作有进栈(push)和出栈(pop)。当栈中不存在任何元素时称为空栈,此时进行出栈操作或者读取栈顶元素是一种错误。栈的实现既可以通过顺序表,也可以使用链表来实现。使用顺序表实现的栈称为顺序栈,使用链表实现的称为链式栈。由于栈的插入删除特性,因此栈具有“后进先出(LIFO)”的特点。考虑到栈在实际中的应用情况,栈一般需要实现以下操作:
- 进栈操作:Push
- 出栈操作:Pop
- 判断是否为空:IsEmpty
- 清空栈:MakeEmpty
- 读取栈顶元素:Top
栈的链表实现
根据分析,栈在使用链表实现时,为了方便可以使用头插法并从头部弹出的结构实现。在STL的实现中,既可以采用deque作为底层容器,也可以采用list作为底层容器。
仿照《数据结构与算法分析-C语言描述》的定义,基本定义如下所示
1 | template <typename DataType> |
如上所示,栈的主要数据成员为栈大小和一个辅助哑节点,如下依次实现栈的各函数
- 压栈,采用头插法
1 | template <typename DataType> |
- 出栈,如果栈为空则抛出异常
1 | template <typename DataType> |
- 判断栈是否为空
1 | template <typename DataType> |
- 清空栈
1 | template <typename DataType> |
- 返回栈顶元素,如果出错则抛出异常
1 | template <typename DataType> |
- 返回栈大小
1 | template <typename DataType> |
- 析构函数,清空栈
1 | template <typename DataType> |
栈的数组实现
栈的数组实现可以直接使用STL的vector作为底层容器,这样数组大小可以动态调整,但是为了方便,这里使用固定数组大小的方式实现,因此会出现栈满的情况。使用数组实现的的栈定义如下:
1 | template <typename DataType> |
如上所示,数组实现的栈只保存栈容量、栈大小以及指向栈存储位置的指针,以下依次实现各函数:
- 构造函数
1 | template <typename DataType> |
- 压栈,如果栈满则抛出异常
1 | template <typename DataType> |
- 出栈,如果栈为空则抛出异常
1 | template <typename DataType> |
- 判断栈是否为空
1 | template <typename DataType> |
- 清空栈
1 | template <typename DataType> |
- 返回栈顶元素,如果出错则抛出异常
1 | template <typename DataType> |
- 返回栈大小
1 | template <typename DataType> |
- 析构函数,清空栈
1 | template <typename DataType> |
代码测试
基本的算法测试和异常捕捉代码如下所示:
1 |
|