【数据结构】-顺序栈(初始化栈顶指针为0)

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. 栈顶指针为-1和0的区别
    在遇到相关问题时,一定要注意看清初始化栈顶指针的值
    (1)当初始化为-1时,栈顶指针指向的是当前栈中的实际位置,而当初始化为为0时,栈顶指针指向的是下一次要插入的位置。
    (2)在进行入栈和出栈的操作时,二者核心操作是相反的。
    (3)在获取栈顶元素的操作中,如果初始化栈顶为0,那么需要先对指针减1才能取到栈顶元素的值,这点与初始化栈顶为-1时的操作有所不同。并且,如果函数定义中参数使用了引用传递,那么栈顶指针还需要再加1,保持栈顶指针原来的位置。如果使用值传递,则不需要,因为值传递不会改变原来的栈。
  2. 顺序栈的缺点
    顺序栈是由静态数组实现的,和顺序表一样,它也存在着容量不可改变的缺点,如果刚开始申请的内存空间过大,又存在内存浪费的问题。
    如何解决这个问题呢,一种是仍然使用顺序存储,使用共享栈来提高内存空间的利用率;另一种则是使用链式存储,引入链栈,这两种方式将在接下来的文章中继续讨论。
  • 14
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
顺序栈是一种基于数组实现的,它的特点是具有随机存取的特性。顺序栈的基本运算包括进、出和查看顶元素。进操作将元素插入到顶,出操作将顶元素删除并返回,查看顶元素操作返回顶的元素值,但不修改的状态。 在C语言中,顺序栈的存储结构可以使用一个一维数组来存放中的元素,同时使用一个指示器top来指示顶的位置。在进行进和出操作时,需要更新top的值,使其指向顶元素。 下面是一种常见的顺序栈的定义和基本操作的示例代码: ```c // 定义中元素的数据类型 typedef int StackElementType; // 定义顺序栈的存储结构 #define Stack_Size 100 // 的最大容量 typedef struct { StackElementType elem[Stack_Size]; // 用数组存放中元素 int top; // 栈顶指针 } SeqStack; // 初始化顺序栈 void Init_SeqStack(SeqStack *S) { S->top = -1; // 初始时为空,栈顶指针置为-1 } // 进操作 void Push_SeqStack(SeqStack *S, StackElementType x) { if (S->top == Stack_Size - 1) { printf("已满,无法进"); return; } S->top++; // 栈顶指针加1 S->elem[S->top] = x; // 将新元素放入顶位置 } // 出操作 StackElementType Pop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空,无法出"); return -1; // 返回一个特殊值表示出错 } StackElementType x = S->elem[S->top]; // 获取顶元素的值 S->top--; // 栈顶指针减1 return x; // 返回顶元素的值 } // 查看顶元素 StackElementType GetTop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空"); return -1; // 返回一个特殊值表示出错 } return S->elem[S->top]; // 返回顶元素的值 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值