《考研408数据结构》第三章2(栈、队列应用)复习笔记

前面已经学过了【栈】和【队列】的知识点,现在还有最后一部分就是他两的【实际应用】,做几遍选择题就行了,有套路不难。

一、栈的应用(手算题)

1、对于【括号配对】的应用

对于栈的第一个应用就是【括号匹配】,在编译器里如果一对括号缺少左括号、缺少右括号,编译器都会报错显示,这就是由栈来实现的。硬性要求就是两点:1、左右括号不能少,必须对应上;2、形状必须一样,不能左边小括号、对右边花括号

那么【栈 匹配括号的规则】非常简单:

  • 1、【左括号】依次入栈
  • 2、【右括号】不入栈,从左往右每遇到一个【右括号】就出栈一个【左括号】与之匹配

在这个规则下,那么出现以下这三情况肯定就是出现了【括号不匹配】的错误

  • 1、出现出栈的【左括号】和这个【右括号】形状不匹配,那后面都不用对比了,说明出错了
  • 2、出栈完栈空了,但是还有【"单身" 右括号】(没有左括号匹配),那就错了
  • 3、遍历完【右括号】都找到【配对的左括号】了,但是栈里还遗留【左括号】,也是错

2、表达式求值

除了括号匹配,那么计算式子也用到了栈。比如下面式子,人类计算的时候可以找到中间的括号,根据计算优先级来算,但是计算机看不懂,这时候就要用其他的表达式来表达这个计算式,并利用栈。

为了方便计算机运算,诞生了这3种计算表达式,分别为:

  • 【中缀表达式】:也就是人类视角的计算表达式

  • 【后缀表达式】:又叫 "逆波兰表达式",计算机看得懂,不需要界限符(括号)

    • 规则:
      • 每两个数之间的操作,把【两个操作数】按顺序放左边,【运算符】放最右
      • 也就是说【每两个数】必须右边带一个【运算符】,两个操作数也顺序绝对不可反
      • 另外对于人类计算,虽然有的时候一个计算表达式会出现左、右都有优先级平等的【2个操作数计算】,逻辑上左边先算和右边先算都一样,但是对于算法的【确定性】:对 相同的输入===>只能得到相同的输出,所以只能规定【先计算 左边 优先级第一两数计算
    • 【后缀】换算成【中缀】怎么算
      • 从左往右数【运算符】,没遇到一个运算符就把左边的【两个操作数】跟它计算,结果放回这两个数的位置,依次类推
  • 【前缀表达式子】:又叫 "波兰表达式",计算机看得懂,不需要界限符(括号)

    • 规则:
      • 反过来,每两个数之间的操作,把【两个操作数】按顺序放右边,【运算符】放最左
      • 也就是说【每两个数】必须左边带一个【运算符】,两个操作数也顺序绝对不可反
    • 【前缀】换算成【中缀】怎么算
      • 和【后缀】规则一样,只不过顺序是从右往左罢了

3、栈对函数调用的应用

简单概括规则:

  • 1、函数调用时,会需要一个栈空间来存【被调用的函数信息】,具体存:
    • 调用返回地址:
      • 上一级父函数里,【调用该函数的代码 的 下一行代码地址】
      • 这样,当该函数执行完后,才知道要返回原函数的哪个位置,继续原来的代码流程
    • 实参:
      • 父函数里【调用该函数时 传入的实际参数的值】
    • 局部变量:
      • 【该调用函数里 使用的局部变量】,这就是为什么被调用函数里变量变了,只要不return回原函数,就不会影响原函数对应的同名变量
  • 2、【每调用一个函数】就要【入栈该函数信息】
  • 3、【最后一层被调用的函数】先执行完【出栈】

4、栈对递归的应用

结合上面函数调用的例子,【递归】对栈的使用就很好理解了,每递归一层函数,就压入一次栈;直到最后一层递归,满足条件返回确切值,然后就依次将递归函数出栈,简单看一下就好

【注意】

  • 记住【非递归算法】效率高于【递归算法】!!!
  • 【"非递归形式" 改写 "递归形式"】、【"消除递归"】的意思都是===>用普通循环的形式代替递归,那么普通循环就不需要用到栈

二、栈的应用(机算)

1、【后缀表达式】、【中缀表达式】计算机怎么用【栈】计算

【后缀表达式】计算

  • 对后缀表达式从左往右扫描,扫到【操作数】就【入栈】
  • 扫到【运算符】就出栈栈顶的【2个操作数】参与计算,计算完的结果马上又入栈
  • 如此反复,最后栈只会剩一个数,也就是结果数

【前缀表达式】计算

  • 和【后缀】反过来就行,一样的规则,只不过是从右往左遍历扫描

2、【中缀】怎么转换成【后缀】、【前缀】

【中缀】转【后缀】规则:(从左往右遍历中缀)

  • 1、遇到【操作数】:和计算反过来,不入栈,直接输出
  • 2、遇到【运算符】:
    • 和计算规则一样,乘除优先级最高、加减优先级低,乘和除优先级相等,加和减也相等
    • 只要栈顶元素比自己优先级低,或者栈顶是左括号,就直接入栈;如果栈顶元素优先级大于等于自己,那就先依次出栈
  • 3、遇到【界限符】:
    • 是【左括号】直接入栈
    • 是【右括号】不用入栈,把栈里最靠栈顶的【左括号】上面的【运算符】全部出栈,最后【左括号】也出栈(但是只出栈,不输出)
      【中缀】转【前缀】规则:以上逻辑从右往左来一遍就行

3、【中缀表达式】怎么机算?

当然中缀表达式也并非不能用计算机机算,我们代码写的是【中缀表达式】,肯定不可能一开始我们就输入【后缀表达式】然后机算;但是如果先【中缀 转 后缀】、再【后缀机算】又有点慢。于是,【中缀表达式机算】直接用【两个栈】,使用【中缀 转 后缀】+【后缀机算】同时结合运算

规则:

  • 1、设置两个栈:【运算符栈】、【操作数栈】
    • 【操作数栈】:按【后缀机算】的逻辑从左往右依次入栈;
    • 【运算符栈】:按【中缀 转 后缀】的逻辑从左往右,依次入栈 优先级高的运算符 或 左括号
  • 2、一个【运算符】出栈,就出【2个操作数】
    • 一起运算,算完的结果再马上入【操作数栈】
  • 3、最后运算的最终结果放【操作数栈】,两个栈就【操作数栈】剩一个结果元素

三、队列的应用

有个印象就够了,知道哪些应用会用到【队列】就行

1、二叉树的【层序遍历】

多说无益,看图理解:

扫描到一个元素,就把【它】和它的【孩子节点】加入队列

然后这个元素出队,如此往复

2、图的【广度优先遍历BFS】

多说无益,看图理解:

扫描到一个元素,就把【它】和它的【孩子节点】加入队列

然后这个元素出队,如此往复

3、操作系统的【FCFS进程管理】

相关推荐
计算机安禾2 小时前
【数据结构与算法】第8篇:线性表(四):双向链表与循环链表
c语言·开发语言·数据结构·c++·算法·链表·visual studio
wangchunting2 小时前
数据结构-线性数据结构
java·开发语言·数据结构
程序员夏末12 小时前
【LeetCode | 第七篇】算法笔记
笔记·算法·leetcode
开源盛世!!12 小时前
3.23-3.25笔记
笔记
豆豆的java之旅14 小时前
软考中级软件设计师 数据结构详细知识点(含真题+练习题,可直接复习)
java·开发语言·数据结构
北顾笙98014 小时前
day07-数据结构力扣
数据结构
hanlin0314 小时前
刷题笔记:力扣第43、67题(字符串计算)
笔记·算法·leetcode
多看书少吃饭15 小时前
Vue + Java + Python 打造企业级 AI 知识库与任务分发系统(RAG架构全解析)
java·vue.js·笔记
了一梨15 小时前
[T113] 交叉编译 OpenCV 4.5.2 + face 模块
linux·笔记·opencv