栈
栈得定义:栈(stack)是限定仅在表尾进行插入和删除操作的线性表
我们把
允许插入和删除得一端称为栈顶(top),另一端称为栈底,不含任何数据元素得栈称为空栈。栈又称后进先出(Last In First Out)的线性表,简称LIFO结构。
栈首先是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系,只不过它是一种特殊的线性表而已。它的特殊之处就在于限制了这个线性表的插入和删除位置,它始终在栈顶进行。这也就使得:栈底是固定的,最先进栈的只能在栈底。
栈的插入操作,叫做进栈,也称压栈、入栈。
栈的删除操作,叫做出栈,也有的叫做弹栈。
如下图:
进栈
出栈
栈的抽象数据类型
ADT 栈(stack)
Data
同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系
Operation
InitStack(*S):初始化操作,建立一个空栈S
DestoryStack(*S):若栈存在,销毁他
ClearStack(*S):将栈清空
StackEmpty(S):若栈为空,返回true,否则返回false
GetTop(*S,e):若栈存在且非空,用e返回S的栈顶元素
Push(*S,e):若栈S存在,插入新元素e到栈S中并称为栈顶元素。
Pop(*S,e):删除栈S中栈顶元素,并用e返回其值
StackLength(S): 返回栈S的元素个数
endADT
栈的顺序存储结构及实现
栈的顺序存储结构:
栈的定义
typedef int SElemType; //SElemType类型根据实际情况而定,这里假设为int
typedef struct{
SElemType data[MAXSIZE];
int top; //指向栈顶
}sqstack;
栈的顺序存储结构–进栈操作
因此对于进栈操作push,其代码如下
//插入新元素e为新的栈顶元素
Status Push(sqstack *s,SElemType e){
if(s->top == MAXSIZE-1){
return ERROR; //栈已满
}
s->top++;
s->data[s->top]=e; //将e赋值给栈顶空间
return ok;
}
栈的顺序存储结构–出栈操作
Status Pop(SqStack *S,SElemType *e){
if(S->top == -1)
return ERROR;
*e = S->data[S->top]; //将要删除的栈顶元素赋值给e
S->top --; //栈顶指针减一
return ok;
}
两栈共享空间
其实栈的顺序存储还是很方便的,因为它只准栈顶进出元素,所以不存在线性表插入和删除时需要移动元素的问题。不过它有一个很大的缺陷,就是必须事先确定数组存储空间大小,万一不够用了,就需要编程手段来扩展数组的容量。对于一个栈,只能考虑周全,设计出合适大小的数组来处理,但对于两个相同类型的栈,可以做到最大限度的利用其事先开辟的存储空间来操作。
数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下标为数组的长度n-1处。这样,如果两个栈增加元素,就是两端点向中间延伸。
如下图:
其实关键思路就是:他们是在数组的两端,向中间靠拢。top1和top2是栈1和栈2的栈顶指针,可以想象,只要它两不见面,两个栈就可以一直使用。
两栈共享空间的结构代码如下:
//两栈共享空间的结构代码如下
typedef struct{
SElemType data[MAXSIZE];
int top1;
int top2;
}sqDoubleStack;
对于两栈共享空间的push方法,我们除了要插入元素值参数外,还需要有一个判断是栈1还是栈2的栈号参数stackNumber,插入代码如下
Status Push(sqDoubleStack *s,ElemType e,int stackNumber){
if(s->top1+1==s->top2) //栈已满,不能在push新的元素
retuen ERROR;
if(stackNumber=1)
s->data[++s->top1]=e; //若栈1则先top+1后给数组元素赋值
else if(stackNumber=2)
s->data[--s->top2]=e; //若栈2则先top2-1后给数组元素赋值
return ok;
}
对于两栈共享空间pop方法
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber){
if(stackNumber = 1){
if(S->top1==-1)
return ERROR; //说明栈1是空栈,溢出
*e=S->data[S->top1--]; //将栈1的栈顶元素出栈
}
else if(stackNumber = 2){
if(S->top2==MAXSIZE){
return ERROR; //说明栈2是空栈
*e=S->data[S->top2++]; //将栈2的栈顶元素出栈
}
}
return ok;
}