栈——后进先出
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
栈的定义
-
栈(stack):是限定仅在表尾进行插入或删除操作的线性表。因此,对于栈来说,表尾端有其特殊含义,称为栈顶(top),相应的,表头端称为栈底(bottom)。不含元素的空表称为空栈。
栈存储结构示意图:
由图可知,栈只能从表的一端存取数据,另一端是封闭的。因此,我们可以形象的认为:
栈是一种只能从表的一端存取数据且遵循 “先进后出” 原则的线性存储结构。
栈的抽象数据类型定义
ADT Stack{
数据对象:D={ai | ai∈ElemSet, i=1,2,…,n,n≥0}
数据关系:R={ <a(i-1) , ai> | a(i-1), ai ∈D,i=1,2,…n} 约定a(n)为栈顶,a1为栈底
基本操作:
InitStack(&S)
// 构造一个空栈S
DestoryStack(&S)
// 销毁栈S
ClearStack(&S)
// 将S清为空栈
StackEmpty(S)
// 若栈S为空栈,返回true,否则返回false
StackLength(S)
// 返回S的元素个数,即栈的长度
GetTop(S)
// 返回S的栈顶元素,不修改栈顶指针
Push(&S,e)
// 插入元素e为新的栈顶元素
Pop(&S,&e)
// 删除S的栈顶元素,并用e返回其值
StackTraverse(S)
//从栈底到栈顶依次对S的每个数据元素进行访问
}ADT Stack
栈的应用
由于栈的操作具有后进先出的固有特性,使得栈成为程序设计中的有用工具。另外,如果问题求解的过程具有“后进先出”的天然特性,则求解的算法中也必然需要利用“栈”。
- 数制转换
- 括号匹配的检验
- 行编辑程序
- 迷宫求解
- 表达式求值
- 八皇后问题
- 函数调用
- 递归调用的实现
栈与一般线性表比较
顺序栈
顺序栈:即利用顺序表实现栈存储结构。
顺序栈的表示和实现
顺序栈的定义
//---------顺序栈的存储结构--------
#define MAXSIZE 100 //顺序栈存储空间的初始分配量
typedef struct
{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈可用最大容量
}SqStack;
顺序栈的初始化
- 顺序栈的初始化操作就是为顺序栈动态分配一个预定义大小的数组空间。
Status InitStack(SqStack &S)
{
//构造一个空栈
S