目录
1、栈定义
栈:是一种特殊的线性表,是限定仅在一端(通常是表尾)进行插入和删除操作的线性表
【后进先出】的线性表简称为LIFO结构
表尾(an端):称为栈顶Top
表头(a1端):称为栈底Base
栈S = (a1,a2,a3,......,an)
入栈(压栈):插入元素到栈顶(表尾)的操作
出栈(弹栈):从栈顶(表尾)删除最后一个元素的操作
逻辑结构:与线性表相同,仍为一对一关系
存储结构:用顺序栈或链栈存储均可,但以顺序栈更常见
运算规则:只能在栈顶运算,且访问时依照后进先出(LIFO)的原则
实现方式:关键是编写入栈和出栈函数,具体实现依顺序栈或链条的不同而不同
2、案例引入
2.1 进制转换
2.2 括号匹配的检验
2.3 表达式求值
算符优先算法:由运算符优先级确定运算顺序的对表达式求值算法
3、栈的基本操作
ADT Stack{
//数据对象
D = {ai|ai属于ElemSet,i=1,2,...,n,n>=0}
//数据关系
R1={<ai-1,ai>|ai-1,ai属于D,i=2,...,n}
//约定an端为栈顶,a1端为栈底
//基本操作:初始化、进栈、出栈、取栈元素等
}ADT Stack
1)初始化操作 InitStack(&S)
操作结果:构造一个空栈S
2)销毁栈操作 DestroyStack(&S)
初始条件:栈S已存在
操作结果:栈S被销毁
3)判断S是否为空 StackEmpty(S)
初始条件:栈S已存在
操作结果:若栈S为空栈,返回TRUE
4)求栈长度 StackLength(S)
初始条件:栈S已存在
操作结果:返回S的元素个数,即栈的长度
5)取栈顶元素 GetTop(S,&e)
初始条件:栈S已存在且非空
操作结果:用e返回S的栈顶元素
6)栈置空操作 ClearStack(&S)
初始条件:栈S已存在
操作结果:将S清空为空栈
7)入栈操作 Push(%S,e)
初始条件:栈S已存在
操作结果:插入元素e为新的栈顶元素
8)出栈操作 Pop(%S,&e)
初始条件:栈S已存在
操作结果:删除S的栈顶元素an,并用e返回其值
4、顺序栈
4.1 关于顺序栈
1)存储方式:同一般线性表的顺序存储结构完全相同,利用一组地址连续的存储空单元存放自栈底到栈顶的数据元素,栈底一般在低地址端
2)附设top指针,指示栈顶元素之上的元素的下标
另设base指针,指示栈底元素在顺序栈中的位置
3)stacksize表示栈可使用的最大容量
4)空栈base ==top是栈空标志
栈满top-base==stacksize
5)栈满时的操作:
1、报错,返回操作系统
2、分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈
6)使用数组作为顺序栈存储方式的特点:简单、方便、但易产生溢出(数组大小固定)
上溢:栈已经满,又要压入元素
下溢:栈已经空,还是弹出元素
注意:上溢是一种错误,问题的处理无法继续,
下溢一般认为是一种结束条件,即问题的结束
4.2 顺序栈的表示
#define MAXSIZE 100 typedef struct{ SElemType *base//栈底元素 SELemType *top//栈顶元素 int stacksize//栈可用最大内存 }SqStack
4.3 顺序栈的初始化
Status InitStack(SqStack &S){//构造一个空栈 S.base = new SElemType[MAXSIZE]; //S.base = (SELemType*)malloc(MAXSIZE*sizeof(SElemType)); if(!S.base)exit (OVERFLOW);//存储分配失败 S.top = S.base; S.stacksize = MAXSIZE; return OK; }
4.4 顺序栈判断栈是否为空
Status StackEmpty(SqStack S){ if(S.top == S.base) return TRUE; else return FALSE }
4.5 求顺序栈长度
int StackLength(SqStack S){ return S.top-S.base }
4.6 清空顺序栈
Status ClearStack(SqStack S){ if(S.base) S.top = S.base; return OK; }
4.7 销毁顺序栈
Status DestroyStack(SqStack &S){ if(S.base){ delete S.base; S.stacksize = 0; S.base = S.tip = NULL; } return OK; }
4.8 顺序栈的入栈
Status Push(SqStack &S,SElemType e){ if(S.top - S.base == S.stacksize)//栈满 return ERROR; *S.top = e; S.top++; //*S.top++ = e; return Ok; }
4.9 顺序栈的出栈
Status Pop(SqStack &S,SElemType e){ if(S.top == S.base)//栈空 return ERROR; --S.top; e=*S.top; //e = *--S.top; return Ok; }
5、链栈
5.1 链栈的定义
typedef struct StcakNode{ SelemType data; struct StcakNode *next; }StackNode,*LInkStack; LinkStack S;
5.2 链栈的初始化
void InitStack(LinkStack &S){ //构造一个空栈,栈顶指针置空 S = NULL; return OK; }
5.3 判断链栈是否为空
Status StackEmpty(LinkStack S){ if(S == NUll) return TRUE; else return FALSE }
5.4 链栈的入栈
Status Push(LinkStack &S,SElemType e){ p = new StackNode //生成新结点P p->data = e; //将新结点数据域置为e p->next = s; //将新结点插入栈顶 S=p; //修改栈顶指针 return OK; }
5.5 链栈的出栈
Status Push(LinkStack &S,SElemType &e){ if(S == NULL) return ERROR; e = S->data; p = S; S = S->next; delete p; return OK; }
5.6 取栈顶元素
Status Push(LinkStack &S,SElemType &e){ if(S != NULL) return S->data; }