顺序栈的基本操作/9/

1、栈是限定仅在表尾进行插入或者删除的操作
2、栈又被称为后进先出的线性表
3、顺序栈:栈的顺序存储结构,利用一组地址连续的存储单元依次存放,自栈底到栈顶的数据元素,同时依附指针top指示栈顶元素在顺序栈中的位置。

初始化栈

栈在使用过程中所需要的最大空间大小很难估计,所以在初始化时,不该定义一个最大容量。而是先分配一个合理容量,再依情况追加。

头文件和宏定义
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define STACKSIZE 100
#define STACKINCRESE 10
#define SElemType int
#define Status int
存储结构
typedef struct {
	SElemType *top;
	SElemType *base;
	int StackSize;
}SqStack;
初始化栈
void InitStack(SqStack &S,int num)
{
	S.base = (SElemType*)malloc(STACKSIZE*sizeof(SElemType));
	S.top = S.base;
	S.StackSize = STACKSIZE;
	if (num > S.StackSize)exit(-1);
	for (int i = 0; i < num; i++) {
		printf("请输入第%d个数据:", i + 1);
		scanf("%d", &*S.top++);
	}
}
销毁栈

销毁栈:使得栈不再存在,需要释放内存
释放内存之后让指针指向NULL,防止野指针

void DestroyStack(SqStack &S){
	for (int i = 0; i < S.StackSize; i++)
	{
		free(S.base);
		S.base++;
	}
	S.base = S.top = NULL;
	S.StackSize = 0;
}
置为空栈

就是把栈置为初始的样子,base和top都在最下面

void ClearStack(SqStack &S){
	S.top = S.base;
}
判断是否为空栈

判断空栈的条件就是base=top,即没有任何数据

bool StackEmpty(SqStack S) {
	if (S.base == S.top)
		return true;
	return false;
}
求栈的长度
int StackLength(SqStack S) {
	return S.top - S.base;
}
取栈顶元素
Status GetTop(SqStack &S) {
	if (S.top == S.base)return -1;
		return *(--S.top);
}
入栈

入栈就要考虑到栈是否以及满了,如果满就需要追加内存

void PushStack(SqStack &S, SElemType e) {
	if (S.top - S.base >= S.StackSize) {
		S.base = (SElemType*)realloc(S.base, (STACKINCRESE + STACKSIZE) * sizeof(SElemType));
		//如果存储空间不够,追加存储
		S.top = S.base + S.StackSize;//让新的top指针指向顶部
		S.StackSize = STACKINCRESE + STACKSIZE;
	}
	*S.top++= e;
}
删除栈顶元素

对于这个功能,我在写代码的时候有一个这样的疑问:

参考代码是直接把栈顶元素取出返回了
top指针下移

我在想不是要删除栈顶元素吗,为什么没有free、置为null的操作。后来我把*S.top输出,结果为要删除的元素的值。

因为在栈中,它通过(*–S.top)的方式来取栈顶元素。在这里直接把S.top指向了要被删除的值,那么这个值,就永远都用指针访问不了,以栈的形式。意义上是实现了删除的操作

Status Pop(SqStack &S, SElemType &e) {
	if (S.base == S.top)
		return -1;
	e = *(--S.top);
	return 1;
	//只是指针下移,但是S.top的值就是当前的e
	//但是根据栈的特点没有办法再去访问它了
}
遍历栈

两种方法
1、从S.top开始–,这个是我自己写的
2、从S.base开始++

法一
之中使用一个新的指针指向S.top,来进行Top的变换

Status GetStack(SqStack &S) {
	printf("此栈现在的元素为:\n");
	if (S.top == S.base) return -1;
	SElemType *p; p = S.top;
	for (int i = 0; i < StackLength(S); i++) {
		p--;
		printf("%d\t", *(p));
	}
	return 1;
}

法二

之中传入一个函数visit函数用来输出访问了的元素

Status visit(SElemType e)
{
	printf("%d\t", e);
	return 1;
}
Status StackTraverse(SqStack S, Status(*visit)(SElemType)){
	if (S.base == S.top)return -1;
	int len = StackLength(S);
	for (int i = 0; i <len; i++) {
		visit(*(S.base++));
	}
	printf("\n");
	return 1;
}

在法二中遇到的问题:

错误代码:

for (int i = 0; i <StackLength(S); i++) {
	visit(*(S.base++));
}

最后输出的元素比原本初始化了的元素数量更少

错误原因:这样写的话,Base一直在变化,循环每走一次,Base就往上移动一次。而在函数StackLength中循环结束条件为S.top-S.baseBase的值一直在增大,所以循环的次数也就一直在减少,导致最后打印的元素数量少了。

解决办法

1、

while (S.top>S.base)
 	visit(*(S.base++));

2、
用len记录长度,控制次数不变

int len = StackLength(S);
	for (int i = 0; i <len; i++) {
		visit(*(S.base++));
	}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值