数据结构-栈和队列-1

简介: 栈和队列是两种常用的、重要的数据结构。栈和队列是限定插入和删除只能在表的端点进行的线性表。普通线性表的插入和删除操作如下:

文章目录


一、前言

二、栈

1. 栈的定义和特点

2. 栈的操作

2.1 入栈示意图

2.2 出栈示意图

3. 栈与一般线性表的对比

4. 顺序栈

5. 链栈

6. 栈与递归

三、队列

1. 队列的定义和特点

2. 队列的操作

3. 队列与一般线性表的对比

4. 顺序队列

5. 链队列

四、单调栈

1. 伪代码

2. 单调栈的应用

五、单调队列

1. 单调队列的应用

2. 与单调栈的异同

2.1 相同点

2.2 不同点

提示:栈和队列相关例题见栈和队列——相关例题


一、前言


  • 栈和队列是两种常用的、重要的数据结构。
  • 栈和队列是限定插入和删除只能在表的端点进行的线性表。
  • 普通线性表的插入和删除操作如下:

bc3084f6cf1b4defaa79b5903575bc1e.png


栈和队列的各项具体操作应该由具体情况进行代码的编写,故在此不进行详细编写,在例题当中会进行体现。


二、栈


  • 栈是先进后出。类似于手电筒的电池,弹夹里的子弹和堆摞的盘子。
  • 如果问题求解的过程具有后进先出的特性时,则求解的算法中也必然需要使用栈。


1. 栈的定义和特点


栈(stack) 是一个特殊的线性表,是限定仅在一端(通常是表尾)进行插入和删除操作的线性表。

由于最后一个进行的要最先被删除,因此又称为后进先出的线性表,检测 LIFO 结构。

插入元素到栈顶(即表尾)的操作,称为 入栈。

从栈顶(即表尾)删除最后一个元素的操作,称为 出栈 。

栈只能在栈顶进行操作



2. 栈的操作

2.1 入栈示意图

5e38d5bf226c472e848b95f7df3cb2e6.png


2.2 出栈示意图

e2a703f8ea154e82b84b6b9a5946367c.png


3. 栈与一般线性表的对比

结构规则 一般线性表
逻辑结构 一对一 一对一
存储结构 顺序栈、链栈 顺序栈、链栈
运算规则 随机存取 后进先出


4. 顺序栈


存储方式:同一般线性表的顺序存储结构完全相同,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。栈底一般在低地址端。

设 top 指针,指示栈顶元素在顺序栈中的位置。但是,为了操作方便,通常 top 指示真正的 栈顶元素之上 的下标地址。

设 base 指针,指示栈底元素在顺序栈中的位置。

使用 stacksize 表示栈可使用的最大容量。

栈满时,要分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈。


92ced58748e64693b3c53524b6f293fa.png


出栈过程与上图类似。


5. 链栈


  • 链栈时运算受限的单链表,只能在 链表头部 进行操作。
  • 链表的头指针就是栈顶,不需要头节点。
  • 空栈相当于头指针指向空,插入和删除仅在栈顶处执行


34e527004654450abbb78baa04351a8d.png


6. 栈与递归


  • 若一个对象部分地包含自己,或者自己给自己定义,则称这个对象是递归地。
  • 若一个过程直接地或间接地调用自己,则称这个过程是递归的过程。
  • 递归必备的三个条件:


  • (1)能将一个问题转变成一个新问题,而新问题与原问题的解法相同或类同,不同的仅是处理的对象,且这些处理对象是变化有规律的。
  • (2)可以通过上述转化而使问题简化。
  • (3)必须有一个明确的递归出口,或称递归的边界。


借助栈改写递归:


  • (1)递归程序在执行时需要系统提供栈来实现。
  • (2)仿照递归算法执行过程中递归工作栈的状态变化可写出相应的非递归程序。
  • (3)改写后的非递归算法与原来的递归算法相比,结构不够清晰,可读性较差,有的还需要经过一系列优化。



三、队列


  • 队列是先进先出。类似于生活中的排队问题。
  • 由于队列的操作具有先进先出的特性,使得队列成为程序设计中解决类似排队问题的有用工具



1. 队列的定义和特点


队列(queue) 是一种先进先出的线性表。在表一端插入(表尾),在另一端(表头)删除。

由于最后一个进行的要最先被删除,因此又称为后进先出的线性表,检测 LIFO 结构。

插入元素到栈顶(即表尾)的操作,称为 入栈。

从栈顶(即表尾)删除最后一个元素的操作,称为 出栈 。

栈只能在栈顶进行操作


2. 队列的操作

  • 关键是掌握入队出队操作,具体实现以顺序队或链队的不同而不同。

bce0cf80dd5a481c8692876f0e6b809c.png



3. 队列与一般线性表的对比

结构规则 一般线性表 栈】队列
逻辑结构 一对一 一对一
存储结构 顺序栈、链栈 顺序队、链队
运算规则 随机存取 先进先出


4. 顺序队列


队列的顺序表示——一维数组。

顺序队的四要素(初始时front=rear=-1):

rear指向队尾元素;front指向队头元素的前一个位置。

队空条件:front = rear 。

队满条件:rear=MaxSize-1 。

元素e进队:rear ++; data[rear] = e 。

元素e出队:front ++; e = data[front] 。


3d939054fa8b4b3a82fb6a0b349f76d3.png


5. 链队列


  • 若用户无法估计所用队列的长度,则应该使用链队列。
  • 链队列运算指针变化状况:
  • (1) 空队列:

f01c2afc3ce04e25b82e09359d1eeeeb.png

(2) 元素 x 入队列

6cdc7857ebe845159c94860255ee2420.png


(3) 元素 y 入队列:

06453cf28fb542a594b3b487fbdca6f5.png


(4) x 出队列:

37bffe1ef825424f9db2e925d7a47ed9.png









相关文章
|
8月前
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
285 1
|
6月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
147 0
栈区的非法访问导致的死循环(x64)
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
11月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
563 77
|
10月前
|
算法 调度 C++
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
267 11
|
11月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
465 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
10月前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
11月前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
272 7
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
1078 9
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
314 59