栈和队列的概念

article/2025/11/7 11:18:03

文章目录

  • 栈、队列和双端队列
    • 队列
    • 双端队列
    • Java 中的栈、队列和双端队列
  • 单调栈和单调队列
  • 二叉堆和优先队列
    • 二叉堆
    • 优先队列
  • 目录

栈、队列和双端队列

栈和队列是常见的数据结构。栈的特点是后进先出,添加元素、删除元素和查看元素都在栈顶操作。队列的特点是先进先出,添加元素在队尾操作,删除元素和查看元素在队首操作。

双端队列比栈和队列更加灵活,可以在双端队列的两端添加元素、删除元素和查看元素。

栈、队列和双端队列都满足每次添加元素、删除元素和查看元素的时间复杂度是 O ( 1 ) O(1) O(1)

栈、队列和双端队列都可以基于数组或链表实现。

栈是一种特殊的线性表,特点是后进先出,最先加入的元素最后取出,最后加入的元素最先取出。

栈的常见操作包括判断栈是否为空和获得栈内元素个数,以及对元素的操作。对元素的操作都位于栈顶,包括以下三种操作:

  • 添加元素:将元素加入栈顶,该操作称为入栈;
  • 删除元素:将栈顶元素删除,该操作称为出栈;
  • 查看元素:获得栈顶元素,不删除元素。

下图为栈的示意,左边为栈底,右边为栈顶。将数字 1 1 1 5 5 5 依次入栈之后,栈的状态如下图所示,此时栈顶元素是 5 5 5,第一个出栈的元素是 5 5 5

图 1

队列

队列是一种特殊的线性表,特点是先进先出,最先加入的元素最先取出,最后加入的元素最后取出。队列有头部和尾部,队列头部称为队首,队列尾部称为队尾,队列内的元素从队首到队尾的顺序符合加入队列的顺序。

队列的常见操作包括判断队列是否为空和获得队列内元素个数,以及对元素的操作。对元素的操作包括以下三种操作:

  • 添加元素:将元素加入队尾,该操作称为入队;
  • 删除元素:将队首元素删除,该操作称为出队;
  • 查看元素:获得队首元素,不删除元素。

需要注意的是,队列的三种对元素的操作所在的位置不同,查看元素和删除元素位于队首,添加元素位于队尾。

下图为队列的示意,左边为队首,右边为队尾。将数字 1 1 1 5 5 5 依次入队之后,队列的状态如下图所示,此时队首元素是 1 1 1,队尾元素是 5 5 5,第一个出队的元素是 1 1 1

图 2

双端队列

双端队列是一种特殊的线性表,同时具有栈和队列的性质,特点是在队首和队尾都可以加入和取出元素。栈和队列都可以基于双端队列实现。

Java 中的栈、队列和双端队列

Java 提供了多种类和接口支持栈、队列和双端队列的实现。

Stack \texttt{Stack} Stack 类是早期版本的栈的实现类,继承自 Vector \texttt{Vector} Vector 类。在后续版本中,JDK 的官方文档不建议使用 Stack \texttt{Stack} Stack 类实现栈的功能,而是建议使用 Deque \texttt{Deque} Deque 接口及其实现类实现栈的功能。

Queue \texttt{Queue} Queue 接口是队列的接口,需要通过实现类完成实例化,常见的实现类包括 ArrayDeque \texttt{ArrayDeque} ArrayDeque 类和 LinkedList \texttt{LinkedList} LinkedList 类。

Deque \texttt{Deque} Deque 接口是双端队列的接口,需要通过实现类完成实例化,常见的实现类包括 ArrayDeque \texttt{ArrayDeque} ArrayDeque 类和 LinkedList \texttt{LinkedList} LinkedList 类。

ArrayDeque \texttt{ArrayDeque} ArrayDeque 类和 LinkedList \texttt{LinkedList} LinkedList 类都可以作为栈和队列的实现类,区别在于, ArrayDeque \texttt{ArrayDeque} ArrayDeque 类的底层实现是循环数组, LinkedList \texttt{LinkedList} LinkedList 类的底层实现是双向链表。根据 JDK 的官方文档, ArrayDeque \texttt{ArrayDeque} ArrayDeque 类作为栈使用时效率高于 Stack \texttt{Stack} Stack 类, ArrayDeque \texttt{ArrayDeque} ArrayDeque 类作为队列使用时效率高于 LinkedList \texttt{LinkedList} LinkedList 类。无论是栈的实现还是队列的实现,都推荐使用 ArrayDeque \texttt{ArrayDeque} ArrayDeque 类。

单调栈和单调队列

单调栈和单调队列是栈和队列的高级应用,可以解决一些复杂的问题。

单调栈和单调队列满足元素的单调性。具体而言,单调栈内从栈底到栈顶的元素依次递增或递减,单调队列内从队首到队尾的元素依次递增或递减。在单调栈和单调队列中添加元素时,必须维护元素的单调性。

向单调栈添加元素时,首先需要检查栈顶元素和待添加元素是否满足单调性,如果不满足单调性则将栈顶元素出栈,直到栈为空或者栈顶元素和待添加元素满足单调性,然后将待添加元素入栈。

向单调队列添加元素时,首先需要检查队尾元素和待添加元素是否满足单调性,如果不满足单调性则将队尾元素出队,直到队列为空或者队尾元素和待添加元素满足单调性,然后将待添加元素入队。

由于普通的队列不支持在队尾将元素出队,因此需要使用双端队列实现单调队列的功能。

单调栈和单调队列的应用需要考虑具体情况。有时需要维护下标信息,因此在单调栈和单调队列中存储的不是元素本身,而是元素下标,下标对应的元素满足单调性。

使用单调栈和单调队列实现通常需要两层循环,但是由于每个元素最多只会在单调栈或单调队列中被添加一次和删除一次,因此时间复杂度是线性复杂度,而不是平方复杂度。

二叉堆和优先队列

优先队列是一种不同于栈、队列和双端队列的数据结构。栈、队列和双端队列的实现原理是线性表,而优先队列的实现原理是二叉堆。

二叉堆

在介绍二叉堆之前,首先需要介绍二叉树和完全二叉树。

二叉树是一个树的结构,每个结点最多有两个子结点,称为左子结点和右子结点。

完全二叉树的性质是,除了层数最大的层以外,其余各层的结点数都达到最大值,且层数最大的层的所有结点都连续集中在最左边。假设完全二叉树有 l l l 层,其中根结点位于第 0 0 0 层,则对于 0 ≤ i < l − 1 0 \le i < l - 1 0i<l1,第 i i i 层有 2 i 2^i 2i 个结点。

二叉堆是一棵完全二叉树,其中的元素按照特定规则排列。常见的例子有小根堆和大根堆。

  • 小根堆的性质是,每个结点的值都小于其子结点的值,根结点的值是堆中最小的;
  • 大根堆的性质是,每个结点的值都大于其子结点的值,根结点的值是堆中最大的。

在二叉堆中添加元素和删除元素时,必须维护二叉堆的性质。以小根堆为例,添加元素和删除元素的操作如下:

  • 添加元素时,假设添加的元素是 x x x,首先将 x x x 添加到末尾,然后比较 x x x 和父结点元素的大小,如果 x x x 小于父结点元素,则将 x x x 和父结点交换,直到 x x x 到达根结点或者大于等于父结点元素;
  • 删除元素时,假设堆中的最后一个元素是 x x x,首先将 x x x 放置到根结点处,然后比较 x x x 和子结点元素的大小,如果 x x x 大于至少一个子结点元素,则将 x x x 和较小的子结点交换,直到 x x x 到达叶结点(没有子结点)或者小于等于全部子结点元素。

考虑以下小根堆。

图 3

8 8 8 添加到小根堆中,首先将 8 8 8 添加到末尾。

图 4

由于 8 8 8 比父结点 15 15 15 小,因此交换,交换后 8 8 8 比父结点 10 10 10 小,因此再次交换,此时 8 8 8 不再比父结点 5 5 5 小,因此停止交换。添加元素操作结束。

图 5

在添加 8 8 8 之后,删除元素。删除堆顶元素 5 5 5,将最后一个元素 15 15 15 放置到根结点处。

图 6

由于 15 15 15 比两个子结点元素都大,因此和较小的子结点 8 8 8 交换,交换后 15 15 15 比较小的子结点 10 10 10 大,因此和较小的子结点 10 10 10 交换,此时 15 15 15 不再比子结点 30 30 30 大,因此停止交换。删除元素操作结束。

图 7

假设二叉堆中的元素个数是 n n n,二叉堆的层数是 l l l。根据上述例子可知,在二叉堆中添加元素和删除元素时,需要维护二叉堆的性质,时间复杂度是 O ( l ) O(l) O(l),由于 O ( l ) = O ( log ⁡ n ) O(l) = O(\log n) O(l)=O(logn),因此二叉堆的添加元素和删除元素的时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

优先队列

不同于栈的后进先出和队列的先进先出,优先队列中的每个元素都有优先级,优先级最高的元素位于队首,也是最先取出的元素。

Java 的 PriorityQueue \texttt{PriorityQueue} PriorityQueue 类是优先队列类,继承自 AbstractQueue \texttt{AbstractQueue} AbstractQueue 抽象类。 PriorityQueue \texttt{PriorityQueue} PriorityQueue 类的实现原理是二叉堆,底层实现是数组,二叉堆满足堆顶元素为优先级最高的元素。创建优先队列的时候可以自定义优先队列中的元素的比较方法,从而自定义优先级。

由于 Java 的优先队列的实现原理是二叉堆,因此优先队列的添加元素和删除元素的时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn),查看元素的时间复杂度是 O ( 1 ) O(1) O(1),其中 n n n 是优先队列中的元素个数。

目录

  1. 栈题目:文件夹操作日志搜集器
  2. 栈题目:括号的最大嵌套深度
  3. 栈题目:有效的括号
  4. 栈题目:棒球比赛
  5. 栈题目:删除最外层的括号
  6. 栈题目:删除字符串中的所有相邻重复项
  7. 栈题目:用栈操作构建数组
  8. 栈题目:两数相加 II
  9. 栈题目:逆波兰表达式求值
  10. 栈题目:使括号有效的最少添加
  11. 栈题目:平衡括号字符串的最少插入次数
  12. 栈题目:最小栈
  13. 栈题目:行星碰撞
  14. 栈题目:验证栈序列
  15. 栈题目:检查替换后的词是否有效
  16. 栈题目:反转每对括号间的子串
  17. 栈题目:移除无效的括号
  18. 栈题目:简化路径
  19. 栈题目:括号的分数
  20. 栈题目:函数的独占时间
  21. 栈题目:字符串解码
  22. 栈题目:解析布尔表达式
  23. 栈题目:有效括号的嵌套深度
  24. 栈题目:删除字符串中的所有相邻重复项 II
  25. 栈题目:迷你语法分析器
  26. 栈题目:设计浏览器历史记录
  27. 栈题目:基本计算器
  28. 栈题目:基本计算器 II
  29. 栈题目:文件的最长绝对路径
  30. 栈题目:标签验证器
  31. 队列题目:无法吃午餐的学生数量
  32. 队列题目:最近的请求次数
  33. 队列题目:用队列实现栈
  34. 队列题目:用栈实现队列
  35. 队列题目:按递增顺序显示卡牌
  36. 队列题目:设计循环队列
  37. 队列题目:设计循环双端队列
  38. 单调栈题目:去除重复字母
  39. 单调栈题目:移掉 K 位数字
  40. 单调栈题目:找出最具竞争力的子序列
  41. 单调栈题目:132 模式
  42. 单调栈题目:每日温度
  43. 单调栈题目:接雨水
  44. 单调栈题目:股票价格跨度
  45. 单调栈题目:最大宽度坡
  46. 单调栈题目:子数组的最小值之和
  47. 单调栈题目:柱状图中最大的矩形
  48. 单调栈题目:最大矩形
  49. 单调队列题目:绝对差不超过限制的最长连续子数组
  50. 单调队列题目:满足不等式的最大值
  51. 单调队列题目:和至少为 K 的最短子数组
  52. 优先队列题目:最后一块石头的重量
  53. 优先队列题目:数据流中的第 K 大元素
  54. 优先队列题目:拼车
  55. 优先队列题目:合并K个升序链表
  56. 优先队列题目:滑动窗口最大值
  57. 优先队列题目:数据流的中位数
  58. 优先队列题目:多次求和构造目标数组
  59. 优先队列题目:数组的最小偏移量

http://chatgpt.dhexx.cn/article/oofxDE8I.shtml

相关文章

栈和队列详解

文章目录 前言一、栈&#xff1a;1.栈的基本概念&#xff1a;2.如何实现栈&#xff1f;3.栈代码演示&#xff1a; 二、队列&#xff1a;1.队列的基本概念&#xff1a;2.如何实现队列&#xff1f;3.队列代码演示&#xff1a; 总结 前言 栈和队列也属于线性表&#xff0c;但是它…

【数据结构】栈和队列详细分析(全)

目录 1.前言2.栈的定义与特点2.1顺序栈的定义2.2顺序栈的操作2.3链栈的定义2.4链栈的操作 3.队列的定义与特点3.1循环队列3.2循环队列的操作3.3链队的定义3.4链队的操作 4.总结 1.前言 栈和队列是两种重要的线性结构。从数据结构角度看&#xff0c;栈和队列也是线性表&#xf…

【Python数据结构系列】❤️《栈(顺序栈与链栈)》——❤️知识点讲解+代码实现

灵魂拷问&#xff1a;为什么要学数据结构&#xff1f; 数据结构&#xff0c;直白地理解&#xff0c;就是研究数据的存储方式。数据存储只有一个目的&#xff0c;即为了方便后期对数据的再利用。因此&#xff0c;数据在计算机存储空间的存放&#xff0c;决不是胡乱的&#xff0c…

数据结构——栈与队列

目录 一、栈 1.栈的定义 2.栈的分类与基本操作 1. 顺序栈 2.链栈 3.栈与递归的实现 1.递归的简单描述 2.递归过程及与栈的关联 3.递归过程示意图 二.队列 1.队列的定义 2.队列的分类与基本操作 1.顺序队列 2.链队列 3.循环队列 1.假溢出 2.循环队列 3.循环队列相…

栈与队列详解

目录 申明1. 栈的定义1.1 栈的定义1.2 进栈出栈变化形式 2. 栈的抽象数据类型3. 栈的顺序存储结构及实现3.1 栈的顺序存储结构3.2 栈的顺序存储结构——进栈操作3.3 栈的顺序存储结构——出栈操作 4. 两栈共享空间5. 栈的链式存储结构及实现5.1 栈的链式存储结构5.2 栈的链式存…

栈与队列(超详细)

目录 一、栈&#xff08;Stack&#xff09;1、什么是栈&#xff1f;2、栈的常见方法3、自己实现一个栈&#xff08;底层用一个数组实现&#xff09; 二、队列&#xff08;Queue&#xff09;1、什么是队列&#xff1f;2、队列的常见方法3、队列的实现&#xff08;单链表实现&…

C语言---栈和队列

严格来说,栈和队列都属于线性表 "一对一" 栈:"先进后出" 队列: "先进先出" 栈 栈只能从一端存取,另一端是封闭的 在栈中,不论是存还是取,都必须遵循"先进后出"的原则 >栈是一种只能从表的一端存取数据,且遵循"先进后出…

数据结构与算法——栈和队列

&#x1f60a;数据结构与算法——栈和队列 &#x1f680;前言&#x1f680;栈&#xff08;satck&#xff09;&#x1f6a2;栈的定义&#x1f6a2;共享栈&#xff08;节省空间&#xff09;&#x1f6a2;栈的表示和实现&#xff08;顺序栈&#xff09;&#x1f47b;顺序栈的定义&…

数据结构:栈和队列(Stack Queue)【详解】

友情链接&#xff1a;数据结构专栏 目录 栈和队列【知识框架】 栈一、栈的基本概念1、栈的定义2、栈的常见基本操作 二、栈的顺序存储结构1、栈的顺序存储2、顺序栈的基本算法&#xff08;1&#xff09;初始化&#xff08;2&#xff09;判栈空&#xff08;3&#xff09;进栈&a…

web 移动端开发基础

web 移动端开发基础 文章目录 web 移动端开发基础了解视口相关内容meta 视口标签掌握二倍图用法物理像素 & 物理像素比多倍图二倍精灵图做法 了解移动端常见选择方案掌握移动端常见问题解决方案移动端常见的布局方式流式布局&#xff08;百分比布局&#xff09;flex 布局 -…

Web移动端

1.PC端和移动端的区别: PC端:屏幕大 用网页固定版心,要考虑浏览器兼容问题,(布局:浮动&#xff0b;定位&#xff0b;标准流) 移动端: 手机屏幕小&#xff0c;网页宽度多数为100%&#xff0c;是适配手机屏幕宽度 移动端则基本不需要考虑兼容性问题&#xff0c;放心大胆使用CS…

移动端网页开发基础

文章目录 前言一、浏览器1.pc端常见浏览器2.移动端常见浏览器 二、视口1.布局视口layout viewport2.视觉视口visual viewport3.理想视口ideal viewport 三、二倍图1.物理像素和物理像素比2.二倍图用法 四、移动端开发选择1.单独制作移动端页面2.响应式兼容pc移动端3.移动端常见…

20.【移动端Web开发之响应式布局】

文章目录 【移动端Web开发之响应式布局】前端小抄(20)一、响应式开发1.1 响应式开发原理1.2 响应式布局容器 二、Bootstrap前端开发框架2.1 Bootstrap简介2.2 Bootstrap使用2.3 布局容器 三、Bootstrap栅格系统3.1 栅格系统简介3.2 栅格选项参数3.3 列嵌套3.4 列偏移3.5 列排序…

H5移动web开发

目录 1、H5 的新特性有哪些&#xff1f;C3 的新特性有哪些&#xff1f; 2、如何使一个盒子水平垂直居中&#xff1f; 方法一&#xff1a;利用定位&#xff08;常用方法,推荐&#xff09; 方法二&#xff1a;利用 margin:auto 方法三&#xff1a;利用 display:table-cell 方法四…

手摸手带你学移动端WEB开发

HTML常用标签总结手摸手带你学CSSHTML5与CSS3知识点总结 好好学习&#xff0c;天天向上 本文已收录至我的Github仓库DayDayUP&#xff1a;github.com/RobodLee/DayDayUP&#xff0c;欢迎Star ⭐⭐⭐⭐⭐转载请注明出处&#xff01;⭐⭐⭐⭐⭐ 链接&#xff1a;https://blog.c…

移动端网页开发(一)

一、项目代码初始化 1.打开index.html将<meta></meta>标签补充完整 <html><head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width,initial-scale1.0&#xff0c;minimum-scale1.0,maximum-…

web移动开发

web移动开发 手机内置浏览器&#xff1a; Android&#xff1a;Andriod BrowserIOS&#xff1a;Mobile SafariBlackBerry&#xff1a;WebkitSymbian S60&#xff1a; Web Browser for S60 其浏览器的核心都是基于Webkit 智能手机Web浏览器的特点: 有限的屏幕尺寸触屏、缩放硬…

移动端页面开发

移动端页面开发需要掌握的…… 移动端开发指的是&#xff1a;需要适配移动设备的网页开发移动开发与pc端开发没有本质的区别&#xff0c;使用的也还是HTML/CSS/JS的技术 一、移动端与pc端开发的区别在于&#xff1a; 1.浏览器不同 手机浏览器是webkit的天下&#xff0c;就目…

从零开始学习移动端Web开发

背景 近年来&#xff0c;随着智能手机的普及&#xff0c;移动端开发受到了异常的关注。从传统的安卓、IOS原生手机系统应用开发&#xff0c;转向了移动端Web开发或者是混合开发&#xff0c;既然有需求&#xff0c;那就让我们一起来学习移动端Web开发吧。本文旨在让读者以最快的…

移动端网站开发

受限于流量太少&#xff0c;以前的手机网站无法做成像现在一样的效果&#xff0c;只能通过超链接的形式实现简单的网页 随着3G&#xff0c;4G&#xff0c;5G的商用&#xff0c;我们的流量越来越多&#xff0c;网速越来越快。越来越多的应用开始去开发网页版。 移动端仿真 未来…