由于栈本身就是线性表,于是栈也有顺序村存储和链式存储两种实现方式
栈的顺序存储——顺序栈
栈的链式存储——链栈
存储方式:同一般线性表的顺序存储结构完全相同,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,栈底一般在低地址端
(1)附设top指针,指示栈顶元素在顺序栈中的位置
(2)另设base指针,指示栈底元素在顺序栈中的位置
但是,为了方便操作,通常top指示真正的栈顶元素之上的下标地址,另外用stacksize表示栈可使用的最大容量
空栈:base == top 是栈空标志
栈满:top - base == stacksize
栈满时的处理方法:
(1)报错,返回操作系统
(2)分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈
使用数组作为顺序栈存储方式的特点:简单、方便、但容易产生溢出(数组固定大小)
上溢(overflow):栈已经满,又要压入元素
下溢(underflow):栈已经空,还要弹出元素
上溢是一种错误,使问题的处理无法进行;而下溢一般认为是一种结束条件,即问题处理结束
顺序栈的表示:
#define MAXSIZE 100
typedef struct{
SElemType base;//栈底指针
SElemType top;//栈顶指针
int stacksize;/栈可用最大容量
}SqStack;
算法:
(1)初始化
Status InitStack(SqStack &S){ //构造一个空栈
S.base = new SElemType[MAXSIZE];//分配空间
if(!S.base) exit (OVERFLOW);//存储分配失败
S.top =S.base;//栈顶指针等于栈底指针
S.stacksize = MAXSIZE;
return OK;
}
(2)判断顺序栈是否为空
Status StackEmpty(SqStack S){
//若栈为空,返回TRUE;否则,返回FALSE
if(S.top ==S.base)
return TRUE;
else
return FALSE;
}
(3)求顺序栈的长度
int StackLength(SqStack S)
{
return S.top - S.base;
}
(4)清空顺序栈
Status ClearStack(SqStack S){
if(S.base) S.top= S.base;
return OK;
}
(5)销毁顺序栈
Status DestroyStack(SqStack &S){
if(S.base){
delete S.base;
S.stacksize = 0;
S.base = S.top = NULL;
}
return OK;
}
(6)顺序栈的入栈
步骤:1)判断是否栈满,若满则上报出错
2)元素e压入栈顶
3)栈顶指针加1
算法:
Status Push(SqStack &S,SElemType e){
if(S.top - S.base == S.stacksize)//栈满
return ERROR;
S.top++e;(S.top =e ; S.top++;)
return OK;
}
(7)顺序栈的出栈
步骤:1)判断是否栈空,若空则出错(下溢)
2)获取栈顶元素e
3)栈顶指针减1
算法:
Status Pop(SqStack &S,SElemType &e){
if(S.top == S.base)
return ERROR;
e=*—S.top;(—S.top; e = —S.top)
return OK;
}
