栈的顺序表示
利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。栈底一般在低地址端。
- 设置top指针:指示栈顶元素在顺序栈中的位置。
- 设置base指针:指示栈底元素在顺序栈中的位置。
- 用stacksize表示栈可使用的最大容量。
但是,为了方便操作,通常top指示的是栈顶元素之上的下标地址。如下图,
例子:
建立一个栈,其stacksize=4,以此为例对顺序栈做一些说明。
-
空栈:base==top是栈空的标志。
-
栈满:top-base==stacksize
-
栈满时的处理方法:
- 报错,返回操作系统
- 分配更大的空间,作为栈的存储空间,将原栈的内容移入到新栈。
-
使用数组作为顺序栈存储方式的特点:简单、方便、但易产生溢出(数组的大小固定)
- 上溢:栈满,又要压入元素。
- 下溢:栈空,还要弹出元素。
上溢是一种错误,使问题的处理无法进行;而下溢一般认为是一种结束条件,即问题处理结束。
栈的具体类型定义:
#define MAXSIZE 100
typedef struct
{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈可用的最大容量
}SqStack;
上图指针相减的结果是数组元素相差的个数,能这样操作的前提是两个指针必须指向同一个数组。
顺序栈的实现
- 顺序栈的初始化
Status InitStack(SqStack& S)
{
S.base = new SElemType[MAXSIZE];
if (!S.base)
exit(OVERFLOW); //存储分配失败
S.top = S.base; //栈顶指针等于栈底指针
S.stacksize = MAXSIZE;
return OK;
}
- 判断顺序栈是否为空
Status StackEmpty(SqStack S)
{
if (S.top == S.base)
return TRUE;
else
return FALSE;
}
- 求顺序栈的长度
int StackLength(SqStack S)
{
return S.top - S.base;
}
- 清空顺序栈
Status ClearStack(SqStack S)
{
if (S.base)
S.top = S.base;
return OK;
}
- 销毁顺序栈
Status DestroyStack(SqStack &S)
{
if (S.base)
{
delete S.base;
S.stacksize = 0;
S.base = S.top = NULL;
}
return OK;
}
- 顺序栈入栈操作
具体步骤:
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;
}
- 顺序栈出栈操作
具体步骤:
1.判断是否栈空,若空则出错(下溢)
2.栈顶指针减1
3.获取栈顶元素e
Status Pop(SqStack& S, SElemType e)
{
if (S.top == S.base) //等价于if(StackEmpty(S))
return ERROR;
e = *--S.top; //等价于--S.top;e=*S.top;
return OK;
}