数据结构:栈和队列

简介: 学习简单数据结构中的栈和队列

1、栈

1.1栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈。出数据也在栈顶。

~D@RUB1[)@ZGPG1G{)3I@WV.png

1.2 栈的实现

1.2.1 栈创建:栈可以用链表也可以用数组来创建,但一般是用数组,因为在数组尾上插入数据,其代价比较小。

1.2.2:栈的入栈,也叫压栈:在实现压栈之前,我们必须定义一下,指向栈顶的top,是指向元素的下一个位置还是元素的位置。我们这里使用的是top==0,指向元素下一个位置的方法。

~@{3BJ)_3TI[E[V7WG]@}_D.png

压栈的时候,只需要将数据插入到top的位置,然后让top移动到下一个位置即可。

2P3RRG}KZN[SIB9NG4BBG4L.png

1.2.3 栈的出栈 由于遵循后进先出,自然是从数组的尾部进行出栈。也就是top--的这个位置开始出栈。

`JPX{D~F(2GHJC7UMBLV`HQ.png

完整代码放在gitee仓库中:Stack List: 数据结构之栈的操作

1.3 括号匹配问题        链接:20. 有效的括号 - 力扣(LeetCode)

题目:给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

    1. 左括号必须用相同类型的右括号闭合。
    2. 左括号必须以正确的顺序闭合。

    思路:使用栈来进行判断,将字符串中的左括号入栈,然后提取栈顶中的字符,和没入栈的右括号进行匹配。

    T_)DS5_NDDDA9YJ`KITMYW1.png

    但是要注意,如'( ( ) '这样的例子,奇数个的时候,匹配成功了一次,剩下的没得匹配,在最后返回的bool值的时候,要进行栈的判空。以下是使用c语言实现的代码:

    5PG~`GDPBQ]1USQ`N%W33HX.png

    2、队列

    2.1 队列的概念及结构

    队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。可以将队列的增删操作想象成打饭排队,在队尾排队,在队头的窗口打饭,然后离开,而且不允许插队!

    1RDT9S{5$22T2P84`02WZCS.png

    2.2 队列的实现

    队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低,因为要挪动数据。

    7N5Y3XWUI6Q7G6XX%3HTBP7.png

    _53}K%YSZ17AZ2_NL0J{VP0.png

    C8A8${PFV}~48PE9Y99W2BY.png

    代码实现:

    WOB7(CM}HOPEZ09]E2$6PMH.png

    BXZ93YOJW8Q8G97LACONXS8.png

    2.3 设计循环队列  题目链接:622. 设计循环队列 - 力扣(LeetCode)

    思路:对于循环队列,我们使用数组的形式来实现循环队列。为什么呢?因为在出队尾元素的时候,链式结构需要遍历一边,找出队尾的上一个元素,而在数组中,只需要根据下标找出即可。循环队列最主要的问题是,如何判断队满和队空?

    队空:rear == front,即头尾的相等。

    队满:如果我们将队满的条件也设为rear==front,这显然很不对。因此,我们可以在在原本的数组长度,即队列长度n的基础上,再增加一个空间,这个空间是不放数据的,让rear指向它。于是,判满的条件是(rear+1)%(n+1),这样,就能判断队满。

    BG9Q35~[N1SRYK5D`TRD$ZU.png

    另外:计算循环队列中的有效长度:现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(其中的n,n-1放了数据):(rear-front+n)%n

    题目的代码:

    L8BG7G$@[TP_BZUEZNV[%VL.png

    3.两道面试题:

    3.1 用队列实现栈  题目链接:225. 用队列实现栈 - 力扣(LeetCode)

    解题思路:由于队列遵循先进先出,也就是在饭堂打饭的时候,先排队的先打完饭。而栈,是后进先出,那么我们可以使用两个队列,始终留一条空的队列来存放另外一条队列的元素,然后剩下最后一个元素直接出队。

    HG({T}X5W6J3Z3AVAVNQ36I.png

    以下是代码:(是使用c语言来写,队列的实现需要自己来实现)

    NH{VJ]_RI)UDN8HYHI`@%4R.png

    3.2 用栈实现队列 题目链接:232. 用栈实现队列 - 力扣(LeetCode)

    解题思路:本题也使用两个栈来实现队列,因为栈是后进先出的,通过画图,就可以发现,只要把一条栈上的元素放到另外一条栈上,那么元素都会颠倒过来,然后对这一条栈进行出栈,就是出队的顺序了!

    ]A_L%_V3T)JW8G}[H%IK2)P.png

    4EPFYFV]O_BV](`R2R}L67A.png

    以上,就是栈和队列的实现,还有其相关的题目的思路啦!如果有哪里不对的,恳请大伙指出!

    相关文章
    |
    1月前
    |
    存储 C语言 C++
    【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
    本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
    142 77
    |
    2天前
    |
    DataX
    ☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
    ### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
    |
    1月前
    |
    存储 C++ 索引
    【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
    【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
    43 13
    【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
    |
    1月前
    |
    存储 C语言 C++
    【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
    本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
    46 9
    |
    1月前
    |
    C++
    【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
    【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
    38 7
    |
    3月前
    |
    存储 缓存 算法
    在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
    在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
    99 5
    |
    3月前
    |
    算法
    数据结构之购物车系统(链表和栈)
    本文介绍了基于链表和栈的购物车系统的设计与实现。该系统通过命令行界面提供商品管理、购物车查看、结算等功能,支持用户便捷地管理购物清单。核心代码定义了商品、购物车商品节点和购物车的数据结构,并实现了添加、删除商品、查看购物车内容及结算等操作。算法分析显示,系统在处理小规模购物车时表现良好,但在大规模购物车操作下可能存在性能瓶颈。
    71 0
    |
    3月前
    |
    C语言
    【数据结构】栈和队列(c语言实现)(附源码)
    本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
    328 9
    |
    3月前
    |
    存储 算法
    非递归实现后序遍历时,如何避免栈溢出?
    后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
    53 1
    |
    3月前
    |
    存储 算法 Java
    数据结构的栈
    栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
    116 21