顺序栈-初始化栈顶指针为0
- 1.头文件及类型定义
- 2.顺序栈类型定义
- 3.函数声明
- 4.基本操作
- 4.1 初始化顺序栈
- 4.2 判空
- 4.3 入栈
- 4.4 出栈
- 4.5 读取栈顶元素
- 4.6 main函数
- 5.小结
1.头文件及类型定义
#include<stdio.h>
#define MaxSize 10 //定义顺序栈中元素的最大个数
#define ElemType int
2.顺序栈类型定义
typedef struct {
ElemType data[MaxSize]; //静态数组存放栈中元素
int top; //栈顶指针,一般来说存放数组的下标
}SeqStack;
3.函数声明
/*函数声明*/
void InitStack(SeqStack& S); //1.初始化顺序栈
bool StackEmpty(SeqStack S); //2.判空
bool Push(SeqStack& S, ElemType x); //3.入栈
bool Pop(SeqStack& S, ElemType& x); //4.出栈
bool GetTop(SeqStack S, ElemType& x); //5.读取栈顶元素
4.基本操作
4.1 初始化顺序栈
//1.初始化栈
void InitStack(SeqStack& S) {
S.top = 0; //初始化栈顶指针为0
}
4.2 判空
//2.判空
bool StackEmpty(SeqStack S) {
return (S.top == 0);
}
4.3 入栈
//3.入栈操作:新元素入栈(先存再加)
bool Push(SeqStack& S, ElemType x) {
if (S.top == MaxSize) //栈满,报错
return false;
S.data[S.top] = x; //新元素先入栈:在栈顶指针所指位置放入x
S.top++; //栈顶指针再加1
/*
以上两句与此句等价:S.data[S.top++] = x;
请注意是S.top++,而不是++S.top
*/
return true;
}
4.4 出栈
//4.出栈操作:栈顶元素出栈(先减再取)-栈顶元素只是逻辑上被删除了,实际上还残留在内存中
bool Pop(SeqStack& S, ElemType& x) {
if (S.top == 0) //栈空,报错
return false;
S.top--; //指针指针先减1
x = S.data[S.top]; //栈顶元素再出栈:返回栈顶元素的值x
/*
以上两句与此句等价:x = S.data[--S.top];
请注意是--S.top,而不是S.top--,注意与上面的入栈操作对比
*/
return true;
}
4.5 读取栈顶元素
//5.读取栈顶元素操作
bool GetTop(SeqStack& S, ElemType& x) {
if (S.top == 0) //栈空,报错
return false;
x = S.data[--S.top];
S.top++; //若SeqStack不是引用类型,则此句不用加
//以上两句代码建议画图,与初始化指针为-1的顺序栈有所区别
return true;
}
4.6 main函数
int main() {
SeqStack S; //声明一个顺序栈(分配内存空间)
/*1、初始化栈*/
InitStack(S);
/*2、判空*/
if (StackEmpty(S))
printf("当前栈空!\n");
else
printf("当前栈非空!\n");
/*3、入栈操作*/
ElemType e1;
printf("请输入入栈元素的值:");
scanf("%d", &e1);
if (Push(S, e1))
printf("新元素入栈成功!\n");
else
printf("栈已满,新元素入栈失败!\n");
/*4、读取栈顶元素*/
ElemType e2 = -1;
if (GetTop(S, e2))
printf("读取栈顶元素成功,当前栈顶元素值为:%d\n", e2);
else
printf("栈已空,读取栈顶元素失败!\n");
/*5、出栈操作*/
ElemType e3 = -1;
if (Pop(S, e3))
printf("栈顶元素出栈成功,出栈元素值为:%d\n", e3);
else
printf("栈已空,栈顶元素出栈失败!\n");
/*6、读取栈顶元素*/
ElemType e4 = -1;
if (GetTop(S, e4))
printf("读取栈顶元素成功,当前栈顶元素值为:%d\n", e4);
else
printf("栈已空,读取栈顶元素失败!\n");
return 0;
}
5.小结
- 栈顶指针为-1和0的区别
在遇到相关问题时,一定要注意看清初始化栈顶指针的值。
(1)当初始化为-1时,栈顶指针指向的是当前栈中的实际位置,而当初始化为为0时,栈顶指针指向的是下一次要插入的位置。
(2)在进行入栈和出栈的操作时,二者核心操作是相反的。
(3)在获取栈顶元素的操作中,如果初始化栈顶为0,那么需要先对指针减1才能取到栈顶元素的值,这点与初始化栈顶为-1时的操作有所不同。并且,如果函数定义中参数使用了引用传递,那么栈顶指针还需要再加1,保持栈顶指针原来的位置。如果使用值传递,则不需要,因为值传递不会改变原来的栈。 - 顺序栈的缺点
顺序栈是由静态数组实现的,和顺序表一样,它也存在着容量不可改变的缺点,如果刚开始申请的内存空间过大,又存在内存浪费的问题。
如何解决这个问题呢,一种是仍然使用顺序存储,使用共享栈来提高内存空间的利用率;另一种则是使用链式存储,引入链栈,这两种方式将在接下来的文章中继续讨论。