1.栈的定义
栈是限定仅在表尾进行插入和删除操作的线性表.、
我们把允许插入和删除的的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据的数据元素的栈称之为空栈。
栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。
理解栈的定义需要注意的情况
首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表,定义中的只在线性表的表尾进行插入和删除操作,这里的表尾是指的栈顶而不是栈底。
它的特殊之处在于限制了这个线性表的插入和删除位置,它始终在栈顶进行,这就使得栈底是固定的,最先进只能在栈底。
2.栈的操作
栈的插入操作,叫做进栈,也称压栈、入栈。
栈的删除操作,叫做出栈,也有的书籍交做弹栈
3.进栈出栈的变化形势
注意:最先进栈的元素不一定是最后出栈的。这是因为栈对线性表的插入和删除位置进行了限制,但是并没有对元素的进出时间进行限制,也就是说不必等所有的元素都进栈的情况下,事先进栈的元素就可以出栈,
例如我们现有3个整型元素1,2,3一次进栈,会有以下这几种出栈次序:
1.第一种: 1,2,3进,再3,2,1出
2.第二种:1进,1出,2进,2出,3进,3出,所以出栈顺序为1,2,3.
。。。。 等等五种情况。
4.栈的抽线数据类型
ADT 栈(stack)
DATA
同线性表,元素具有相同的类型,相邻元素具有前驱和后继关系。
Operation
InitStack(*S): 初始化操作,建立一个空栈。
DestroyStack(*S): 若栈存在,则销毁它。
ClearStack(*S): 将栈清空。
StackEmpty(*S): 若栈为空,则返回true,否则返回false。
GetTop(*S, *e): 若栈存在且非空,用e返回栈顶元素。
Push(*s, e): 若栈存在,插入新元素e到栈S中并成为栈顶元素。
Pull(*s,*e) : 删除栈S中的栈顶元素,并用e返回其值。
StackLength(s): 返回栈S的元素个数。
endADT
5.栈的顺序存储结构及其实现
- 栈的顺序存储结构
栈的结构定义:
typedef int SElemType; /*SElemtype类型根据实际情况来定,这里假设为 int类型*/
typedef struct
{
SElemType data[MAXSIZE];
int top; /*用于栈顶指针*/
}SqStack ;
- 栈的顺序存储结构-进栈操作
/*插入元素e为新的栈顶元素*/
Static Push(SqStack *s, SelemType e)
{
if (S->top == MAXSIZE -1 ) /*栈满*/
{
return ERROR;
}
S->top++; /*栈顶指针加1*/
S->data[S->top] = e; /*将新插入的元素赋值给栈顶空间*/
return OK;
}
- 栈的顺序存储结构-出栈操作
<span style="white-space:pre"> </span> /*若栈不为空,则删除栈顶元素,用e返回其值,并返回OK,否则返回ERROR*/
Static Pop(SqStack *s, SelemType *e)
{
if (S->top == MAXSIZE -1 ) /*栈满*/
{
return ERROR;
}
*e = S->data[S->top] ; /*将要删除的栈顶元素赋值给e*/
S->top++; /*栈顶指针减1*/
return OK;
}
这两个操作的时间复杂度均为O(1).
6.两栈共享空间
用一个数组来存储两个栈,实现方式:
数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个为数组的末端,即下标为数组长度的n-1处,这样两个栈要是增加元素都是从两个端点向中间延伸。
假设其中一个栈的栈顶指针为top1,另一个为top2,则top1 =-1时,这个栈为空,另一个当top2 = n-1时为空。当top1+1 ==top2时两个栈满。
- 两栈共享空间的结构代码实现
/*两栈共享的空间结构*/
typedef struct
{
SElemType data[MAXSIZE];
int top1; /*栈1的栈顶指针*/
int top2; /*栈2的栈顶指针*/
}SqdoubleStack
- 两栈共享空间的Push方法
/*插入元素e为新的栈顶元素*/
Status Push(SqdoubleStack *S, SElemType e, int stackNumber)
{
if (S->top1 +1 == S->top2)/*栈已经满了,不能再Push新元素了*/
return ERROR;
if (stackNumber ==1) /*栈1有元素进栈*/
{
s->data[++s->top1] = e; /*若是栈1则先top1+1后给数组元素赋值*/
}
else if(stackNumber ==2) /*栈2有元素进栈*/
s->data[--s->top2] = e; /*若是栈2则先top2-1后给数组元素赋值*/
return OK;
}
- 两栈共享空间的Pop方法
/*若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR*/
Status Pop(SqdoubleStack *S, SElemType *e, int stackNumber)
{
if (stackNumber ==1) /*栈1有元素进栈*/
{
if (S->top1 == -1)/*说明栈1是空栈*/
return ERROR;
*e = s->data[s->top1--] ; /*将栈1的栈顶元素出栈 */
}
else if(stackNumber ==2) /*栈2有元素进栈*/
{
if (S->top2 == MAXSIZE)/*说明栈2是空栈*/
return ERROR;
*e = s->data[s->top1++] ; /*将栈2的栈顶元素出栈 */
}
return OK;
}