首页 > 其他分享 >03栈与队列

03栈与队列

时间:2024-06-24 12:09:19浏览次数:16  
标签:03 存储 下标 队列 元素 矩阵 表达式

当n个不同元素进栈时,出栈元素不同排列的个数为
$$
\frac{1}{n+1}C_{2n}^{n} = \frac{(2n)!}{(n+1)!n!}
$$
该公式为卡特兰数(Catalan)公式

栈的输出序列

如果输入次序是顺序输入,可以观察最先一个输出的元素,若最先输出的是最后输入的元素,则输出序列一定是倒序且唯一

共享栈

栈底位置相对不变,让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间中间延申

共享栈更有效利用空间,两个栈空间相互调节,只有当整个存储空间均被占满才会出现栈空间上溢出

栈的基本操作

void InitStack(&S); //初始化
void GetTop(S,&x); //读栈顶元素
bool Pop(&S,x); //出栈
bool Push(&S,x); //入栈
bool StackEmpty(S); //判空操作
void DestroyStack(&S); //销毁操作

任何应用场景只要涉及最后加入的部分,最先执行的过程,都适合使用栈去实现,即LIFO

栈的应用——括号匹配

算法过程

  • 遍历括号序列,遇到左括号压入栈中
  • 每遇到右括号,栈顶元素弹出,与右括号进行匹配
    • 若栈目前为空,结束遍历并认定序列非法
    • 若弹出元素与右括号为同种括号则继续,反之直接结束遍历并认定序列非法
  • 括号序列遍历完成,若栈不为空,则说明序列非法

栈的应用——表达式求值

前/中/后缀表达式:运算符在两个操作数前面/中间/后面
前缀表达式=波兰表达式
后缀表达式=逆波兰表达式

两个操作数如果没有运算先后顺序,中缀表达式转换为前缀/后缀表达式可能有多个结果

  • 后缀表达式,运算符号出现的先后次序,与中缀表达式的符号运算顺序相同

同时为了保证算法结果唯一性(运算次序手算与机器计算结果相同),采用“左优先”原则:只要坐标的运算符能先计算,就先按计算左边

算法过程

((15/(7-(1+1))x3)-(2+(1+1)))

中缀转后缀
15 7 1 1 + - / 3 x 2 1 1 + + -

  • 中缀表达式根据运算规则以及左优先原则,转为后缀表达式
  • 后缀表达式从左往右遍历,遇到操作数直接压栈
  • 每遇到一个运算符,运算符最近的两个数出栈(先出栈的是右操作数),进行运算后结果作为新的一个操作数再压入栈中
  • 若无法弹出两个数,则说明表达式非法
  • 表达式遍历完成后,若只剩下一个操作数,则说明表达式合法,该操作数则为表达式结果

中缀转前缀表达式,则采用“右优先”原则
表达式从右往左遍历,其余和上述方法一致,注意进行预算结合时,先出栈的是左操作数

栈的应用——表达式转化

中缀表达式转后缀表达式

注意该算法栈空间需要预留足够,可能会出现栈溢出问题

算法过程:

  • 中缀表达式从左往右遍历,遇到操作数直接加入后缀表达式
  • 遇到左括号直接压栈,遇到右括号逐个将栈内元素弹出加入后缀表达式,直至弹出左括号,同时左右括号不加入后缀表达式
  • 遇到运算符,逐个将栈内优先级高于或等于当前运算符的所有运算符弹出并加入后缀表达式,若过程中遇到左括号或者栈为空则停止,最后将当前运算符入栈

中缀表达式计算(表达式转化+表达式求值)

  • 初始化两个栈,A栈用于存放操作数,B栈用于存放运算符
  • 中缀表达式从左往右遍历,遇到操作数压入A栈
  • 遇到操作符或者括号,将栈内优先级高于或等于当前运算符的运算符依次弹出,每弹出一个运算符从A栈弹出两个操作数进行运算,并将结果压回A栈。(括号匹配同表达式转化算法)

栈的应用——递归

  • 适合使用递归算法解决的问题,一般是具有可将原始问题规模转换为属性相同,但规模更小的问题的解决思路
  • 递归算法具有递归表达式以及边界条件
  • 递归算法具有很高的空间复杂度,因此在使用该算法时注意考虑栈溢出情况
  • 递归算法也可以自定义栈的方式,把递归算法转变为非递归算法
  • 递归算法可能会包含很多重复计算

队列

队列和栈的逻辑结构相同,两者的区别在于删除、插入操作的限定规则不同

一般情况下,链式队列的队头都是放在链表头部,方便出队。
链式队列空间虽然是动态分配的,但是不代表长度不受限制,长度仍受内存空间限制
链式队列和顺序队列出队、入队时间复杂度均为O(1),均可以顺序访问,但链式队列无法通过队首、队尾指针确定队列长度,顺序队列则可以
链式队列出队操作通常只要修改头指针,但是当队列只有一个元素且发生删除时,需要修改尾指针rear=front

队列的基本操作

void InitQueue(&Q); //初始化
void GetHead(Q,&x); //读队头元素
bool DeQueue(&Q,&x); //出队
bool EnQueue(&Q,x); //入队
bool QueueEmpty(Q); //判空操作

队列的应用

  • 树层次遍历
  • 图广度优先遍历
  • 操作系统中应用
    • 多个进程争夺有限系统资源时,FCFS/FIFO先来先服务是一种常用策略。
    • 通过设置一个队列缓冲区,让任务在缓冲区中以先进先出的形式,有序执行

双端队列

队列队头、队尾均可以进行插入、删除操作的数据结构,常考察输出序列的合法性。

双端队列还有两种衍化结构:

  • 输出受限的双端队列

    一端可以插入、删除,但是另一端只能插入的双端队列

  • 输入受限的双端队列

    一端可以插入、删除,但是另一端只能删除的双端队列

双端队列可以模拟为一个堆栈,因此栈能够输出的序列,双端队列也能够输出

数组与特殊矩阵

  • 一维数组,个数组元素大小相同,且物理上连续存放,因此具有随机存储特性

    • 假定一维数组起始地址为LOC,b[i]元素的存储地址为LOC+i*N*sizeof(ElemType)
    • 考研题目中,数组默认下标以0开始,除非题目特殊说明
  • 二维数组的存储方式可采用行优先存储以及列优先存储,从而具备随机存储特性

    • 假定二维数组起始地址为LOC
    • 按行优先存储,b[i][j]元素的存储地址为LOC+(i*N+j)*sizeof(ElemType)
    • 按列优先存储,b[i][j]元素的存储地址为LOC+(j*M+i)*sizeof(ElemType)
  • 普通矩阵可以按照二维数组进行存储

    • 在描述矩阵元素时,行、列号通常从1开始,而描述数组时通常下标从0开始,需要注意
    • 普通存储空间规模为N*N

压缩存储的目的就是只存储非0元素,其余0元素不占用空间。
一般题目,如果求压缩数组的下标通项公式,可采用特殊值带入求解
注意题目中元素下标是0开始还是1开始

对称矩阵,矩阵内任意a(i,j)=a(j,i)

  • 对称矩阵压缩存储:只存储主对角线+下/上三角区元素
  • 按照行优先元素存储到一维数组,共需要存储$\frac{n(n+1)}{2}$个元素,即最后一个元素的下标为$\frac{n(n+1)}{2}$-1
    • 为了方便随机存取,按照行优先原则,假定存储主对角线以及下三角元素,当i≥j时,a(i,j)元素的下标为$\frac{i(i-1)}{2}$+j-1;当i<j时,利用a(i,j)=a(j,i)即可获得该元素的值,即a(i,j)元素的下标为$\frac{j(j-1)}{2}$+i-1
  • 按照列优先元素存储到一维数组,数组大小仍然不变,但a(i,j)元素的下标则变为(n+n-1+n-2+...+n-(j-1)+1)+(i-j)

上/下三角元素,除了主对角线和上/下三角区,其余元素均相同

  • 压缩存储:三角区元素存储在一维数组中,额外增加一个位置存储常量
  • 按照行优先元素存储到一维数组,共需要存储$\frac{n(n+1)}{2}$+1个元素
    • 为了方便随机存取,按照行优先原则,对于下三角矩阵,当i≥j时,a(i,j)元素的下标为$\frac{i(i-1)}{2}$+j-1;当i<j时,a(i,j)元素的下标均为$\frac{n(n+1)}{2}$
    • 对于上三角矩阵,,当i≥j时,a(i,j)元素的下标为(n+n-1+n-2+...+n-(i-1)+1)+(j-i);当i<j时,a(i,j)元素的下标均为$\frac{n(n+1)}{2}$

三对角矩阵(带状矩阵,三边矩阵),矩阵内下标|i-j|>1时元素值为0,即主对角线上的相邻元素可以为非0元素,其余元素值均为0

  • 按行优先存储,除了第一行、最后一行只有2个元素,其余行均有3个元素,因此共需要存储3n-2
  • |i-j|>1,元素值直接放回0,这部分元素不需要存储在一维数组中
  • 对于b[k]元素,他在数组中为第k+1个元素,前i-1行共有3(i-1)-1个元素,前i行共有3i-1个元素,因此3i-4≤k+1≤3i-1,则满足$i≥\frac{k+2}{3}$,向上取整i=$⌈$(k+2)/3$⌉$即可(或向下取整i=$⌊$(k+2)/3+1$⌋$)
  • 同时有k=2i+j-3,所以第k+1个元素的下标就已经获得了

稀疏矩阵,非零元素个数远少于矩阵元素个数

稀疏矩阵的特点是非零元素数量较少
稀疏矩阵无法更具矩阵元素行列下标快速定位矩阵元素,不支持随机存取

  • 压缩存储方式1,通过顺序存储三元组<行,列,值>,但是无法进行随机存取
  • 压缩存储方式2,十字链表法,具有两个指针域数组right、down,分别指向第i行的第一个元素、第j列第一个元素,每个非零数据节点包含行、列、数值域、指向同列下一个元素的指针以及指向同行下一个元素的指针

标签:03,存储,下标,队列,元素,矩阵,表达式
From: https://www.cnblogs.com/GKJerry/p/18264781

相关文章

  • 'MMDetection3D'+'waymo-open-dataset-tf-2-6-0'+'pytorc2.3.1+cu121'安装
    安装pytorc2.3.1+cu121步骤1.创建并激活一个conda环境condacreate-nmmdpython=3.8-ycondaactivatemmd步骤2.基于PyTorch官方说明安装PyTorch,例如:pip3installtorchtorchvisiontorchaudio--index-urlhttps://download.pytorch.org/whl/cu121步骤3.验......
  • 链表实现队列
    #include<iostream>#include<stdexcept>//定义链表节点结构structNode{intdata;Node*next;};//链表队列类classLinkedListQueue{private:Node*front;//队头指针Node*rear;//队尾指针public://构造函数,初始化队头和队尾指针......
  • 5034. 【NOI2017模拟3.28】B —— 矩阵树定理和拉格朗日插值的结合
    题目大意给你一棵\(n\)(\(n\le50\))个点的树,可以进行不超过\(k\)次操作,每次断掉一条边,再连上一条边,要求树一直是树,求一共有多少种树的形态。思路把题意转换为对于一个\(n\)个点的完全图,是树边的话权值是\(1\),否则是\(x\)。跑一遍矩阵树定理,矩阵树定理求的是一个图所有生......
  • Leetcode 225. 用队列实现栈 && 232.用栈实现队列(jvav)
    225.用队列实现栈    题目:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。    本题可采用一个队列或两个队列完成,这里我使用一个队列实现栈,更加简洁,理解起来也不难。    栈的特点是先进后出,队......
  • 学生信息管理系统(0.00.03版)加油!!
    #include<bits/stdc++.h> #include<windows.h>usingnamespacestd;voidcout_text(strings){   for(inti=0;i<s.size();i++){      cout<<s[i];      Sleep(50);   }}structStudent{  stringage;  stringgender;};map<s......
  • 后端开发Spring框架之消息 消息队列案例--订单短信通知
    消息队列案例首先我们书写一个业务层接口定义的是发送消息短信消息处理packagecom.bigdata1421.message.service;publicinterfaceOrderService{voidorder(Stringid);}创建业务层的实现类并且我们要重写方法这里就是打印日志将消息打印在控制台再写......
  • 【免费】中国电子学会2024年03月份青少年软件编程Scratch图形化等级考试试卷三级真题(
    青少年软件编程(图形化)等级考试试卷(三级)分数:100 题数:31一、单选题(共18题,共50分)1.   运行程序后,角色一定不会说出的数字是?()A.        2B.        4C.        6D.        8试题编号:20240115-zgq-002试题类型:单选题标......
  • 【免费】中国电子学会2024年03月份青少年软件编程Scratch图形化等级考试试卷一级真题(
    青少年软件编程(图形化)等级考试试卷(一级)分数:100 题数:37一、单选题(共25题,共50分)1.   单击下列哪个按钮,能够让舞台变为“全屏模式”?()A.     B.     C.     D.     试题编号:20240114-hcc-001试题类型:单选题标准答案:D试题难度:一般......
  • 【免费】中国电子学会2024年03月份青少年软件编程Python等级考试试卷一级真题(含答案)
    2024-03Python一级真题分数:100题数:37测试时长:60min一、单选题(共25题,共50分)1. 下列哪个命令,可以将2024转换成'2024'呢?(A)(2分)A.str(2024)B.int(2024)C.float(2024)D.bool(2024)答案解析:本题考察的是str()语句,将数字转换成字符串用到的是str()语句。2. 猴......
  • 【数学】100332. 包含所有 1 的最小矩形面积 II
    本文涉及知识点数学LeetCode100332.包含所有1的最小矩形面积II给你一个二维二进制数组grid。你需要找到3个不重叠、面积非零、边在水平方向和竖直方向上的矩形,并且满足grid中所有的1都在这些矩形的内部。返回这些矩形面积之和的最小可能值。注意,这些......