4.2 顺序栈
栈是一种操作受限的线性表,在第 3 章中已经讲过,逻辑结构数据的存储结构有两种:顺序存储和链式存储。所以,栈也可以用顺序结构和链式结构两种方式表示,本节将介绍顺序结构的表示方法。
4.2.1 顺序栈的存储结构
顺序栈(Sequential Stack)是指利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针 top
指示栈顶元素在顺序栈中的位置。
若以顺序表为例,top
指针所指示的使表尾,在表尾进行元素的插入或删除,时间复杂度都是 O(1)O(1)O(1) ,不需要移动元素。所以,顺序栈和顺序表的存储结构本质是相同的,差别进在于增加了指针,并且规定只能在“表尾”(即栈顶)进行操作。
顺序栈的存储结构:
#define MAXSIZE 100 //顺序栈存储空间的初始分配量
typedef struct{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈可用的最大容量
}SqStack;
-
base
为栈底指针,初始化完成后,栈底指针base
始终指向栈底位置,若base
的值为NULL
,则表明栈结构不存在。 -
top
为栈顶指针,初始值指向栈底。每当插入新的栈顶元素时,指针top
增 1;删除栈顶元素时,指针top
减 1。 -
栈空时,
top
和base
的值相等,都指向栈底;栈非空时,top
始终指向栈顶元素的上一个位置。图 4.2.1 显示了栈中的元素和栈指针之间的关系。 -
stacksize
指示栈可使用的最大容量。
参考图 4.2.1 ,可知顺序栈 S
的“空”“满”的条件:
- 栈空的条件:
S.base == S.top
- 栈满的条件:
S.top - S.base == S.stacksize
4.2.2 顺序栈的基本操作
1. 顺序栈的初始化
顺序栈的初始化就是为顺序栈动态分配一个预定义大小的数组空间。
【算法步骤】
- 为顺序栈动态分配一个最大容量为
MAXSIZE
的数组空间,使base
指向这段空间的基地址,即栈底。 - 栈顶指针
top
初始为base
,表示栈为空。 stacksize
置为栈的最大容量MAXSIZE
。
【算法描述】
Status InitStack(SqStack &S){//构造一个空栈 S
//为顺序栈动态分配一个最大容量为 MAXSIZE 的数组空间
S.base = new SElemType[MAXSIZE];
if(!S.base)
exit(OVERFLOW); //存储分配失败
S.top = S.base; //top 初始为 base, 空栈
S.stacksize = MAXSIZE; //stacksize 置为栈的最大容量 MAXSIZE
return OK;
}
【算法分析】
时间复杂度 O(1)O(1)O(1) 。
2. 顺序栈的入栈
入栈操作:在栈顶插入一个新的元素,如图 4.2.1 所示。
【算法步骤】
- 判断栈是否满,若满则返回
ERROR
。 - 将新元素压入栈顶,栈顶指针加 1。
【算法描述】
Status Push(SqStack &S, SElemType e){
//插入元素 e 为新的栈顶元素
if(S.top - S.base == S.stacksize)
return ERROR; //栈满
// 入栈操作:先赋值,再移动栈顶指针
*(S.top) = e;
S.top++;
return OK;
}
【算法分析】
时间复杂度:O(1)O(1)O(1) 。
3. 顺序栈的出栈
出栈操作:将栈顶元素删除。
【算法步骤】
- 判断栈是否为空,若空则返回 ERROR。
- 栈顶指针减 1,栈顶元素出栈。
【算法描述】
Status Pop(SqStack &S, SElemType &e){
//删除 S 的栈顶元素,用 e 返回其值
if(S.top == S.base)
return ERROR; //栈空
// 正确的出栈操作:先移动指针,再获取元素值
e = *(--S.top); // 等价于: S.top--; e = *S.top;
return OK;
}
【算法分析】
时间复杂度:O(1)O(1)O(1) 。
4. 取顺序栈的栈顶元素
取栈顶元素的操作:当栈非空时,返回当前栈顶元素的值,栈顶指针保持不变。
【算法描述】
SElemType GetTop(SqStack S){
//返回 S 的栈顶元素,不修改栈顶指针
if(S.top != S.base)//栈非空
return *(S.top - 1); //返回栈顶元素值,栈顶指针不变
}
【算法分析】
时间复杂度:O(1)O(1)O(1) 。
例 4.2.1 若一个栈以向量 V[1..n]
存储,初始栈顶指针 top
设为 n+1
,则元素 x
进栈的正确操作是( )。
A. top++; V[top]=x;
\qquad B. V[top]=x; top++;
C. top--; V[top]=x;
\qquad D. V[top]=x; top--;
【解】
初始栈顶指针 top
为 n+1
,说明元素从数组向量的高端地址进栈,又因为元素存储在向量空间 V[1..n]
中,所以进栈时 top
指针先下移变为 n
,之后将元素 x
存储在 V[n]
。
本题答案:C
例 4.2.2 在一个有 nnn 个单元的顺序栈中,假定以地址高端(下标为 n−1n-1n−1 的单元)作为栈底,以 top
作为栈顶指针,则向栈中压入一个元素时,top
的变化是 ( )。
A. top
不变\qquad B. top = n
\qquad C. top = top - 1
\qquad D. top = top + 1
【解】
栈底为 n−1n-1n−1 处,若有元素进栈,该元素应首先占有高地址的单元,因此栈顶指针 top
应减 1。
本题答案:C