初阶数据结构 栈

一. 栈的基本介绍

1. 基本概念

栈是一种线性表 是一种特殊的数据结构

栈顶:进行数据插入和删除操作的一端

另一端叫做栈底

压栈:插入数据叫做压栈 压栈的数据在栈顶

出栈: 栈的删除操作叫做出栈 出栈操作也是在栈顶

栈遵循一个原则 叫做后进先出

(比如说子弹的弹夹 其实就是一种设计好的栈结构)

画图表示如下

在这里插入图片描述

2. 代码结构 (动态数组实现)

因为数组模式相对于链表模式来说 尾插的操作消耗更好些 cpu缓存命中率也更高一些

此外因为静态的数组不能变更空间大小 所以说我们这里用动态数组的代码来实现一下

typedef int StackType;

struct Stack
{
	StackType* a;  //储存数据的大小
	int Top;       //栈顶
	int Capacity;  //数组容量大小 
};

在这里插入图片描述

二. 接口函数实现

1. 初始化栈

这个很简单 初始化栈里面的三个值就好

在这里插入图片描述
代码表示如下

void StackInit(ST* p)
{
	
	p->a = NULL;
	p->Top = 0;
	p->Capacity = 0;
}

我们这里要注意Top为0的时候我们需要先赋值再++

2. 压栈

这里我们需要考虑一个问题

我们压栈的时候是否空间满了呢?

所以在压栈之前我们先写一个Cheak函数来看看栈空间是否满了

	if (p->Top==p->Capacity)
	{
		int NewCapacity = p->Capacity == 0 ? 4: p->Capacity * 2;
		StackType* Tmp = realloc(p->a,NewCapacity*sizeof(StackType));
		if (Tmp==NULL)
		{
			perror("StackPush realloc");
		}
		else
		{
		    //记得要更新容量数据 
		    p->Capacity =Newcapacity;
			p->a = Tmp;
		}
	}

之后我们开始写压栈操作

整体代码表示如下

void StackPush(ST* p, StackType x)
{
	assert(p);
	if (p->Top==p->Capacity)
	{
		int NewCapacity = p->Capacity == 0 ? 4: p->Capacity * 2;
		StackType* Tmp = realloc(p->a,NewCapacity*sizeof(StackType));
		if (Tmp==NULL)
		{
			perror("StackPush realloc");
		}
		else
		{
			p->a = Tmp;
		}
	}

	p->a[p->Top] = x;
	p->Top++;
}

3. 出栈

这个很简单 只需要考虑一个问题

是否删除了过多的数据导致错误

代码表示如下

void StackPop(ST* p)
{
	assert(p);
	assert(p->Top > 0);

	p->Top--;
}

我们可以看到 删除两个数据并没有什么问题
在这里插入图片描述
可是 当我们继续删除数据的时候

在这里插入图片描述
这里出现了断言错误

4. 打印数据

栈的打印数据和我们以前学的其他数据的打印不同!!!

打印出一个数据之后必须要进行出栈操作才可以

代码表示如下

void StackPrint(ST* p)
{
	assert(p);
	while (p->Top>0)
	{
		printf("%d  ", p->a[p->Top - 1]);
		StackPop(p);
	}
}

显示效果如下
在这里插入图片描述

5. 找到个数

这个很简单 返回Top的值就可以

int StackSize(ST* p)
{
    assert(p);
	return p->Top;
}

6. 判断是否为空

这个也很简单 两行代码搞定

bool StackEmpty(ST* p)
{
	assert(p);
	return p->Top==0;
}

7. 摧毁栈

void StackDestroy(ST* p)
{
	assert(p);
	free(p->a);
	p->a == NULL;
	p->Capacity = 0;
	p->Top = 0;
}

释放开辟出的内存空间 之后再指针置空就可以

这个也很简单 这里就不过多介绍了

三. 两道简单的题目

题目一

一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的
顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA

答案是B 遵循后进先出的原则

题目二

若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2 B 2,3,4,1
C 3,1,4,2 D 3,4,2,1

首先来看A选项

我们先压栈1 再出栈1 压栈 2 3 4 再依次出栈就可以 没问题

B选项

我们先压栈 1 2 出栈2 再压栈3 4 再依次出栈就可以 没有问题

C选项

我们先压栈123 出栈3 之后再出栈1 这个就不对了 要想出栈1 必须先出栈2

所以答案是C

D选项

我们先压栈 1 2 3 再出栈3 然后压栈4 再依次出栈就可以 没有问题

以上就是本篇博客的全部内容啦 由于博主才疏学浅 所以难免会出现纰漏

希望大佬们看到错误之后能够不吝赐教 在评论区或者私信指正 博主一定及时修正

那么大家下期再见咯

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值