数据结构-栈和队列-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









相关文章
|
2天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
|
4天前
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
10 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
8天前
|
Linux C++ Windows
栈对象返回的问题 RVO / NRVO
具名返回值优化((Name)Return Value Optimization,(N)RVO)是一种优化机制,在函数返回对象时,通过减少临时对象的构造、复制构造及析构调用次数来降低开销。在C++中,通过直接在返回位置构造对象并利用隐藏参数传递地址,可避免不必要的复制操作。然而,Windows和Linux上的RVO与NRVO实现有所不同,且接收栈对象的方式也会影响优化效果。
|
23天前
|
存储 安全 编译器
缓冲区溢出之栈溢出(Stack Overflow
【8月更文挑战第18天】
46 3
|
24天前
|
测试技术
【初阶数据结构篇】栈的实现(附源码)
在每一个方法的第一排都使用assert宏来判断ps是否为空(避免使用时传入空指针,后续解引用都会报错)。
|
10天前
crash —— 获取内核地址布局、页大小、以及栈布局
crash —— 获取内核地址布局、页大小、以及栈布局
|
10天前
|
存储 程序员 C语言
堆和栈之间有什么区别
【9月更文挑战第1天】堆和栈之间有什么区别
77 0
|
19天前
|
机器学习/深度学习 消息中间件 缓存
栈与队列的实现
栈与队列的实现
35 0
|
24天前
|
测试技术
【初阶数据结构篇】队列的实现(赋源码)
首先队列和栈一样,不能进行遍历和随机访问,必须将队头出数据才能访问下一个,这样遍历求个数是不规范的。
|
29天前
|
算法 C语言 C++
【practise】栈的压入和弹出序列
【practise】栈的压入和弹出序列