栈文档之栈

定义

栈(Stack)只允许在一端进行插入或删除操作的线性表(与队列相比而言,队列是允许在两端进行插入或删除操作的)。

栈只能在栈顶进行插入或删除。如图所示:

在这里插入图片描述
关于栈的一些概念:

  • 栈顶:可以进行插入或删除的一端,不是固定的(每插入或删除一个元素栈顶都会变)。
  • 栈底:不能进行插入或删除的另一端,固定的。
  • 空栈:即不含任何元素的空线性表。
  • 入栈:也称为压栈,即插入操作,将元素从栈顶压入,然后新插入的元素成为新的栈顶元素。
  • 出栈:也称为弹栈,即删除操作,将元素从栈顶弹出,然后下一个元素成为新的栈顶元素。

由栈的定义就可以直到栈的主要特点是先进后出(FILO,First In Last Out),也可以称为后进先出。因为只允许从栈顶入栈,从栈顶出栈,所以后进来的元素在先进来的元素的上方,所以能够先出去。

例如,某个栈 S=(a1, a2, a3, a4, a5),其中 a1 是栈底元素,a5 是栈顶元素。由于栈只能在栈顶进行插入和删除操作,进栈次序依次为 a1, a2, a3, a4, a5,出栈次序为 a5, a4, a3, a2, a1

基本操作

注:

  • 栈的基本操作的名称各不相同,应该说数据结构中的基本操作名称在各大书籍或资料中不尽相同,但表达的意思是相通的。
  • 下面的基本操作中 & 表示引用调用,这是 C++ 的语法,仅是抽象表示,不必在意。但在实际实现中 C 语言采用的是双指针,而 Java 采用的是对象和函数返回值。

无论是顺序栈还是链栈,它的基本操作如下:

  • init(&Stack):初始化一个空栈。
  • isEmpty(Stack):判断栈是否为空。
  • push(&Stack, ele):进栈,若栈未满,则将 ele 插入使之成为新栈顶。
  • pop(&Stack, &ele):出栈,若栈非空,则弹出栈顶元素,并用 ele 返回。
  • getTop(Stack, &ele):读取栈顶元素,但不出栈,若栈非空,则用 ele 返回栈顶元素。
  • size(stack):获取栈中的元素个数。
  • print(stack):从栈顶到栈底打印栈中所有元素。
  • clear(&stack):清空栈。
  • destroy(&stack):销毁栈。

存储结构

栈是一种操作受限的线性表,也有两种存储方式,顺序存储和链式存储。前者称为顺序栈,后者称为链栈

顺序栈

采用顺序存储的栈称为顺序栈,它采用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时设定一个指针(top)指向当前栈顶元素的位置。通常采用数组来实现。

在这里插入图片描述

更多请参考:顺序栈

链栈

采用链式存储的栈称为链栈。链栈的优点是便于多个栈共享存储空间和提高效率,且不存在栈满上溢的清空。通常采用单链表实现,并且规定所有操作都是在单链表的表头进行上的(因为头结点的 next 指针指向栈的栈顶结点)。

注:所谓的栈上溢,是只有在顺序栈才会发生的情况,因为顺序栈分配的空间是有限的,如果栈已满,再进行入栈操作时,就会产生上溢。而链栈是不会出现这种情况的,因为空间是动态分配的。

在这里插入图片描述

更多请参考:链栈

两种存储结构的比较

顺序栈的特性:

  • 空间静态分配,最大空间容量有限制,会存在栈上溢的情况。
  • 必须是一块连续的存储单元。
  • 通常使用数组实现。
  • 插入操作和删除操作很快,都是在栈顶操作。

链栈的特性:

  • 空间动态分配,不需要考虑空间不够的情况,不存在栈上溢的情况。
  • 可以是离散的存储单元,不要求连续。
  • 通常使用单链表实现。
  • 插入操作和删除操作很快,都是在栈顶操作。所以跟顺序栈相比,这个不是明显优势。

其他栈

共享栈

共享栈是顺序栈的变种。利用栈底位置相对不变的特性,可以让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延申,如图所示:

在这里插入图片描述

其中两个栈的栈顶指针都指向栈顶元素。top0=-1 时表示 0 号栈为空,top1=MAXSIZE 时表示 1 号栈为空(这是设定,因为栈顶指针存储的是下标,而 -1MAXSIZE 都表示不合法的下标,所以用来指定初始栈空条件)。当两个栈顶指针相邻(即 top1 - top0 = 1)时,判断栈满。

共享栈能够更加有效地利用存储空间,两个栈的空间相互调节,只会在整个存储空间被栈满时才会发生上溢,存取数据的时间复杂度仍为 O(1)

更多请参考:共享栈

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值