栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
我们允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为 空栈。栈又称为后进先出的线性表,简称LIFO结构。
理解栈的定义需要注意:
1.他是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。是一种特殊的线性表,他的特殊之处就在于限制了这个线性表的插入和删除位置,它始终只在栈顶进行,这也就使得:栈底是固定的,最先进栈的只能在栈底。
栈的插入操作,叫作进栈,也称压栈、入栈。
栈的删除操作,叫作出栈,也有叫作弹栈。
最先进栈的元素,是不是就只能是最后出栈呢?
答案是不一定,要看什么情况。栈对线性表的插入和删除的位置进行了限制,并没有对元素进出的时间进行限制,也就是说,在不是所有元素都进栈的情况下,事先进去的元素也可以出栈,只要保证是栈顶元素出栈就可以。
案例:我们现在是有3个整型数字元素1、2、3依次进栈,会有哪些出栈次序?
第一种:1、2、3进,在3、2、1出。出栈次序为 321.
第二种:1进,1出,2进,2出,3进,3出。出栈次序为:123.
第三种:1进,2进,2出,1出,3进,3出。出栈次序为:213.
第四种:1进,1出,2进,3进,3出,2出。出栈次序为:132.
第五种:1进,2进,2出,3进,3出,1出。出栈次序为:231.
ADT 栈(stack)
DATA
同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。
Operation
InitStack ( *S ) :初始化操作,建立一个空栈S。
DestroyStack( *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; /* 将新插入元素复制给栈顶空间 */
return OK;
}
/* 若栈不空,则删除S的栈顶元素,用 e 返回其值,并返回OK;否则返回ERROR */
status Pop ( SqStack *S , SElemType *e )
{
if ( S ->top == -1 ){
return ERROR;
}
*e = S -> data[S -> top ]; /* 将要删除的栈顶元素赋值给e */
S -> top --; /* 栈顶指针减一 */
return OK;
}
进栈和出栈都没有涉及循环语句,因此时间复杂度均为 O( 1 )。
/* 两栈共享空间结构 */
typedef struct
{
SElemType data[MAXSIZE];
int top1; /* 栈1 栈顶指针 */
int top2; /* 栈2 栈顶指针 */
}SqDoubleStack;
对于两栈共享空间的push方法,我们除了要插入元素值参数值外,还需要添加一个判断栈1还是栈2的参数stackNumber。
/* 插入元素 e 为新的栈顶元素 */
status push ( SqDoubleStack *S , SElemType e, int stackNumber )
{
if ( S -> top1 +1 == 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方法,参数就只是判断栈1 和栈2 的参数stackNumber。
/* 若栈不空,则删除S的栈顶元素,用e 返回其值,并返回ok;否则返回error */
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;
}
原文:https://www.cnblogs.com/cjn93/p/9342845.html