C语言实现顺序栈

栈和队列是两种重要的线性结构。从数据结构的角度看,栈和队列也是线性表,其特殊性在于栈和队列的操作位置都在特定的位置。
引用自严蔚敏的数据结构与算法教材

栈的结构体定义:

typedef struct Stack
{
	int *base;	//栈底指针
	int *top;	//栈顶指针
	int stack_size;	//栈的大小 也就是占用的空间sizeof(ElemType) * size;
}SqStack;

和链表类似 我们首先要初始化顺序栈:

SqStack initSqStack(int n)
{
	SqStack S;
	S.base = (int *)malloc(sizeof(int) * MAX_INIT_SIZE);	//为顺序栈申请一块内存空间 内存空间大小 = sizeof(int) * S.stack_size
	//验证内存空间是否申请成功
	if (S.base == NULL)
	{
		printf("申请内存空间失败!\n");
		exit(1);
	}
	S.top = S.base;	//此时栈底指针base 和 栈顶指针top指向内存中的用一块内存空间
	S.stack_size = MAX_INIT_SIZE;
	for (int i = 0; i < 5; i++)
	{
		printf("请输入第%d个数据:", i + 1);
		scanf("%d", S.top);
		S.top++;
		S.stack_size--;
	}
	return S;
}

但是 与链表相同 在初始化的同时为栈的元素赋值(应该这么说吧 emmmm^ _ ^)
下面画图解释一下为什么在最开始栈底指针base 和 栈顶指针top处在同一位置
在这里插入图片描述
在最开始的时候即栈为空栈时 top 和 base指向同一个地方 当顺序栈中读入了一个数据之后 top指针后移并且顺序栈大小减少1即Size-1 即如图所示

接下来介绍几个基本的操作函数:

//验证是否为空栈
void isEmpty(SqStack S)
{
	if (S.top == S.base)
	{
		printf("栈为空!\n");
	}
	else printf("栈非空!\n");
}

这里稍微重点介绍一下插入元素这个操作:

//向栈中插入元素
SqStack pushElemToStack(SqStack S, int e)
{
	//首先验证栈是否存满元素 如果栈慢就需要增加空间
	if (S.top - S.base >= S.stack_size)
	{
		int *temp = S.base;
		temp = (int *)realloc(S.base, sizeof(int) * (S.stack_size + MAX_CREATE_SIZE));
		if (!temp)
		{
			printf("ERROR!\n");
			exit(1);
		}
		S.base = temp;
		S.top = S.base + S.stack_size;
		S.stack_size += MAX_CREATE_SIZE;
	}
	*S.top = e;
	S.top++;	//以上两句可以合并为:*S.Top++ = e;
	return S;
}

我们将代码拆分 具体介绍:

		int *temp = S.base;
		temp = (int *)realloc(S.base, sizeof(int) * (S.stack_size + MAX_CREATE_SIZE));

这两句代码 都来自于插入操作 之所以要将S.base重新保存 是因为 在下面的申请内存空间的代码中 会改变base的值 但是申请内存空间不一定会成功 所以要将base的值保存到temp中 这样即使申请内存空间失败 原来的栈依然不会受到任何影响

其中realloc()函数和malloc函数的功能类似 但是realloc()函数是重新分配空间 函数的第一个参数就是要改变大小的原内存地址
如果申请内存空间成功的话返回地址 失败则返回NULL 这也是为什么上面要将S.base保存起来的原因
在这里给出realloc函数的函数原型:extern void *realloc(void mem_address, unsigned int newsize);
realloc()函数在<stdlib.h>中(部分编译器还需要<malloc.h>),
用法:指针名=(数据类型
)realloc(要改变内存大小的指针名,新的大小)

		S.base = temp;
		S.top = S.base + S.stack_size;
		S.stack_size += MAX_CREATE_SIZE;

由于realloc函数改变了地址 即栈顶指针的指向也会随之改变:S.top = S.base + S.stack_size;
改变之后的栈大小为原大小+新增大小即:S.stack_size += MAX_CREATE_SIZE;

有了push操作(插入) 也应该有与之对应的pop操作(读取栈顶元素):

//读取栈顶元素
int popElem(SqStack *S)
{
	//首先验证顺序栈是否为空
	if (isEmpty(*S))
	{
		printf("栈为空!\n");
		exit(1);
	}
	--(S->top);
	return *S->top;
}

上最后两句可以合并为一句return * -- S->top
画图描述最后两句核心代码:
在这里插入图片描述

顺序栈的基本操作大概就是这些 如果各位看官觉得有帮助请帮我点赞转发 欢迎理性讨论:1781516638(qq)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值