1 栈的概念
栈(Stack):是限制在表的一端进行插入和删除操作的线性表。又称为后进先出LIFO (Last In First Out)或先进后出FILO (First In Last Out)线性表。
栈顶(Top):允许进行插入、删除操作的一端,又称为表尾。用栈顶指针(top)来指示栈顶元素。
栈底(Bottom):是固定端,又称为表头。
空栈:当表中没有元素时称为空栈。
设栈S=(a1,a2,…an),则a1称为栈底元素,an为栈顶元素,如图3-1所示。
栈中元素按a1,a2,…an的次序进栈,退栈的第一个元素应为栈顶元素。即栈的修改是按后进先出的原则进行的。
ADT Stack{
数据对象:D ={ ai|ai∈ElemSet, i=1,2,…,n,n≥0 }
数据关系:R ={(ai-1, ai)| ai -1, ai ∈D, i=2,3,…,n }
基本操作:初始化、进栈、出栈、取栈顶元素、求栈的长度、判断栈是否为空等
} ADT Stack
采用静态一维数组来存储栈。
◆ 栈底固定不变的;栈顶则随着进栈和退栈操作而变化,用一个整型变量top(称为栈顶指针)来指示当前栈顶位置。
◆ 用top=0表示栈空的初始状态,每次top指向栈顶在数组中的存储位置。
◆ 结点进栈:首先执行top加1,使top指向新的栈顶位置,然后将数据元素保存到栈顶(top所指的当前位置)。
◆ 结点出栈:首先把top指向的栈顶元素取出,然后执行top减1,使top指向新的栈顶位置。
栈的类型定义
define MAX_STACK_SIZE 100 /* 栈向量大小 */
typedef int ElemType ;
typedef struct sqstack
{ ElemType stack_array[MAX_STACK_SIZE] ;
int bottom; //栈底,实为数组下标
int top; //栈顶,实为数组下标
}SqStack ;
栈的初始化
SqStack Init_Stack(void)
{ SqStack S ;
S.bottom=S.top=0 ;
return(S) ;
}
压栈(元素进栈)
Status push(SqStack &S , ElemType e)
/* 使数据元素e进栈成为新的栈顶 */
{ if (S.top==MAX_STACK_SIZE-1)
return ERROR; /* 栈满,返回错误标志 */
S.top++ ; /* 栈顶指针加1,下标为0的位置不放元素 */
S.stack_array[S.top]=e ; /* e成为新的栈顶 */
return OK; /* 压栈成功 */
}
思考:若调换S.top++ 和S.stack_array[S.top]=e 的位置,结果如何?
弹栈(元素出栈)
ElemType pop( SqStack &S)
/*弹出栈顶元素*/
{ if ( S.top==0 )
return ERROR ; /* 栈空,返回错误标志 */
e=S.stack_array[S.top] ;
S.top-- ;
return e ;
}
当栈满时做进栈运算必定产生空间溢出,简称“上溢”。上溢是一种出错状态,应设法避免。
当栈空时做退栈运算也将产生溢出,简称“下溢”。下溢则可能是正常现象,因为栈在使用时,其初态或终态都是空栈,所以下溢常用来作为控制转移的条件。
采用动态一维数组来存储栈。所谓动态,指的是栈的大小可以根据需要增加。
◆ 用bottom表示栈底指针,栈底固定不变;栈顶则随着进栈和退栈操作而变化。用top(称为栈顶指针)指示当前栈顶位置。
◆ 用top=bottom作为栈空的标记,每次top指向栈顶数组中的下一个存储位置(或指向栈顶元素)。
◆ 结点进栈:判断栈是否已满,如果栈满,则重新申请更大的内存空间,然后将数据元素保存到栈顶(top所指的当前位置),然后执行top加1,使top指向栈顶的下一个存储位置;
◆ 结点出栈:首先执行top减1,使top指向栈顶元素的存储位置,然后将栈顶元素取出。
基本操作的实现
1 栈的类型定义
#define STACK_SIZE 100 /* 栈初始向量大小 */
#define STACKINCREMENT 10 /* 存储空间分配增量 */
typedef int ElemType ;
typedef struct sqstack
{ ElemType *bottom; /* 栈不存在时值为NULL */
ElemType *top; /* 栈顶指针 */
int stacksize ; /* 当前已分配空间,以元素为单位 */
}SqStack ;
2 栈的初始化
Status Init_Stack(SqStack *S )
{
S ->bottom=(ElemType *)malloc(STACK_SIZE *sizeof(ElemType));
if (! S -> bottom) //若返回空指针,内存分配失败
return ERROR;
S -> top=S -> bottom ; /* 栈空时栈顶和栈底指针相同 */
S -> stacksize=STACK_SIZE;
return OK ;
}
3 压栈(元素进栈)
Status push(SqStack *S , ElemType e)
{ if (S -> top-S -> bottom>=S -> stacksize-1)
{ S -> bottom=(ElemType *) realloc (S -> bottom, (STACKINCREMENT+STACK_SIZE) *sizeof(ElemType));
/* 栈满,追加存储空间 */
if (! S -> bottom) return ERROR;
S -> top=S -> bottom+S -> stacksize ; //为什么?
S -> stacksize+=STACKINCREMENT ;
}
*S-> top=e;
S -> top++ ; /* 栈顶指针加1,e成为新的栈顶 */
return OK;
}
4 弹栈(元素出栈)
ElemType pop( SqStack *S)
/*弹出栈顶元素*/
{ if ( S->top== S-> bottom )
return ERROR ; /* 栈空,返回失败标志 */
S-> top-- ;
e=*S -> top ;
return e ;
}
ElemType pop( SqStack *S) /*弹出栈顶元素*/
{ if ( S ->top== 0 )
return ERROR ; /* 栈空,返回失败标志 */
S -> top-- ; e =S-> bottom[S ->top];
return e ;
}
ElemType Get_top( SqStack *S) /*弹出栈顶元素*/
{ if ( S ->top== 0 )
return ERROR ; /* 栈空,返回失败标志 */
S -> top-- ; e =S-> bottom[S ->top];
return e ;
}
原文地址:http://blog.csdn.net/wangzi11322/article/details/45361837