数据结构复习笔记(3)

第三章 栈和队列

基本定义

栈是人为规定只能在表尾进行插入或删除的线性表,表尾称为栈顶,表头称为栈底,是一种后进先出LIFO的结构。栈的基本操作和线性表类似

栈的具体实现

栈本质上也是线性表,因此也有顺序存储和链式存储两种实现方式。

对于顺序栈,使用一组地址连续的存储单元存放从栈底到栈顶的数据元素,并附一个用于指示栈顶元素所在位置的指针。对于顺序栈,一般使用动态分配存储空间的方式,使得栈的大小不受限制

对于链栈,一般将头指针作为指向栈顶的指针,新的数据元素使用头插法插入到链栈中

栈的应用场景

  • 数制转换

    由于数制转换时计算顺序和输出顺序相反,可以使用栈来完成这个“翻转”的操作

  • 括号匹配检验

    由于右括号永远对应于它左边最近的对应左括号,可以用入栈、出栈操作来检验括号的匹配情况,以此来判断是否所有括号都匹配上

  • 行编辑程序

    从左往右输入时,显然左侧为栈底,右侧为栈顶,一行即为一个栈

  • 迷宫求解

    本质上就是用栈来手工模拟递归

  • 表达式求值

    使用栈可以实现中缀表达式转换为后缀表达式、计算中缀表达式、计算后缀表达式,思路都是相似的。表达式计算依赖于各个运算符之间的优先级关系。显然,乘、除的优先级高于加、减;由于加减乘除都是左结合(即从左往右算的),对于乘除之间和加减之间,处于前面的优先级较高。

    由于括号里的内容需要先算,左括号对于左侧的运算符来说优先级是最高的,右括号对于左侧的运算符来说优先级是最低的、对于右侧的运算符来说优先级是最高的;由于左括号相当于括号中表达式的开始,对于右侧的运算符来说优先级是最低的。

    下表为运算符之间的优先级关系,每次遇到比前面优先级低的运算符时进行对应操作。表中的!表示遇到该运算符比较时,表达式语法有问题,优先级相等的表示互相消除;#表示起始/结束

    运算符优先级表

递归

一个直接调用自己或通过一系列调用语句间接地调用自己的函数,称为递归函数。从某种意义上看,也是分治思想的一种应用。递归函数在运行过程中,实际上是将程序的运行状态以栈的形式存储,达到层层递归的效果

一般来说,程序在调用一个函数时,会进行以下操作

  • 将要传给被调用函数使用的实参、返回地址等信息传递给被调用函数保存
  • 为被调用函数的局部变量分配存储区
  • 将控制转移到被调用函数入口

在被调用函数返回之前,一般会进行以下操作

  • 保存被调函数的计算结果
  • 释放被调函数的数据区
  • 按照上面调用函数时操作第一步中的返回地址,将控制转移到之前的程序

队列

队列只允许在一端插入元素,在另一端删除元素,是一种先进先出FIFO的线性表结构。允许插入的一端称为队尾,允许删除的一端称为队头。双端队列是可以自己规定两个端点的插入/删除规则的一种队列结构

队列具体实现方式

链队列

由于需要在队尾插入、在队头删除,链队列需要两个指针分别指向链表头和链表尾。在设计删除元素的算法时,要注意处理删除队列中最后一个元素的情况,尤其是队尾指针的赋值

循环队列

循环队列是队列顺序存储结构的实现,使用一组地址连续的存储单元,还要使用两个指针分别指示队头、队尾的位置。在非空的循环队列中,头指针始终指向队列头元素的位置,尾指针始终指向队列尾元素的下一个位置(下一次插入元素可以直接放入)。插入元素后尾指针后移一个位置;删除元素后则将头指针前移一个位置

为了区别循环队列是空是满,循环队列中留出一个位置不存放数据元素。若队列为空,首尾指针指向同一个位置;若队列为满,尾指针的下一个位置为头指针指向位置

posted @   GeorgeHu6  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示