【数据结构】——栈

一、栈的概念和结构

栈其实就是一种特殊的顺序表,其只允许在一端进出,就是栈的数据的插入和删除只能在一端进行,进行数据的插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的元素遵循先进后出LIFO(Last InFirst Out)的原则。

**压栈:**栈的插入操作叫做进栈/压栈/入栈,入栈的位置也是在栈顶。

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

那么我们的栈是要如何进行实现呢?

我们实现栈的话有两种:链表和数组。

如果是使用链表的话,那么我们要是以头为栈顶,那么我们进行头插的话,就需要先考虑链表是否为空的情况,然后我们的头插的结构也是比较麻烦,每次都需要进行节点的申请。

还有就是进行出栈的时候也比较麻烦。

如果我们使用数组,直接使用数组的尾部为栈顶,那么我们的压栈和出栈都可以直接进行,时间复杂度为O(1)。

不过链表和数组都是可以实现的,不过如果使用链表进行实现的话,我们就推荐使用链表的头为栈顶,然后数组的话我们建议使用数组的尾部为栈顶。这样可以使得压栈和出栈的时间复杂度都为O(1)。

二、栈的实现

1、栈的定义

我们上面提到了,我们实现栈,我们底层使用数组来实现,那么其定义和我们前面学习的顺序表基本是一样的,但是就是我们的栈是有一个限制的,就是其只能在一端进行出入。

栈的定义如下:

其实 arr就是我们存储数据的数组,然后top表示当前我们的栈有多少个元素,capacity就表示我们当前的栈最大的容量。

我们定义好后,那么我们对这个栈进行一个初始化:

因为栈的销毁这里也不做多的解释了。

栈的销毁:

下面我们实现栈的压栈:

我们栈的特点就是其只有一端可以进行压栈和出栈的操作,我们前面说到,我们使用数组来实现的话,那么我们是在数组的尾部进行压栈和出栈,那么我们该如何进行压栈呢?

我们在定义栈的时候,我们有一个成员top其是记录当前我们的栈中的有效成员个数的,那么我们的数组是可以通过下标进行插入数据的,不过要注意的是,我们的栈如果此时为空,而且其表示栈的容量的成员也是空的时候,那么我们就需要进行空间申请的,还有就是栈如果满了,那么我们此时也需要进行空间的申请。不过我们发现我们的栈为空和栈满的时候有个共同点,就是我们的top和capacity是i相等的。所以我们再入栈操作的时候,一开始需要先进行判断当前栈的空间是否足够,不够的话我们要进行扩容,然后我们扩容一般是二倍增容。还有一个特殊情况就是刚开始的时候,我们的容量还是0,那么我们此时进行二倍增容是行不通的,所以我们也特殊处理一下。

代码如下:

上面我们实现了压栈,那么我们接下来就实现栈的另外一个功能:出栈

我们要出栈,那么我们的栈就要不为空才行,所以我们可以先写一个函数判断栈是否为空,然后通过这个函数我们就可以进行出栈,要注意的是我们的栈,出栈也是要在栈顶这一端,所以也是在数组的末尾端,那么我们的top进行--操作就可以了,那么就可以使得我们的栈的有效元素个数减-,而且是栈顶的第一个元素。

压栈:

我们栈有时候只是需要取栈顶的元素,并不需要出栈,那么我们也可以写一个函数来实现,我们的取栈顶元素是很简单的,就是访问数组一样,我们就访问下标为top-1的元素即可。

然后我们也可以获取当前栈的实际有效元素个数:

可以看到我们的栈的两个大的功能还是很好实现的,和我们前面的顺序表大致一样,就是其要控制的是,其入栈和出栈的端要一致。

相关推荐
可乐鸡翅好好吃3 小时前
not a genuine st device abort connection的问题
c语言·stm32·单片机·keil
C++实习生6 小时前
powerbuilder9.0中文版
c语言·c++
懒懒小徐8 小时前
2023华为od统一考试B卷【二叉树中序遍历】
数据结构·算法·华为od
MeiYu_1239 小时前
【数据结构与算法】图的基本概念与遍历
数据结构·c++·学习
keepDXRcuriosity9 小时前
动态规划详解及 C/C++ 示例
c语言·c++·动态规划
YuforiaCode11 小时前
第十一届蓝桥杯 2020 C/C++组 蛇形填数
c语言·c++·蓝桥杯
void_sk12 小时前
C/C++复习--C语言中的函数详细
c语言·c++·算法
evolution_language12 小时前
LintCode第485题-生成给定大小的数组,第220题-冰雹猜想,第235题-分解质因数
数据结构·算法·新手必刷编程50题
举一个梨子zz12 小时前
Java—— 集合 List
java·开发语言·数据结构·intellij-idea
千里镜宵烛13 小时前
C++ 哈希表
开发语言·数据结构·c++·哈希算法·散列表