【数据结构】考研真题攻克与重点知识点剖析 - 第 3 篇:栈、队列和数组

本文主要是介绍【数据结构】考研真题攻克与重点知识点剖析 - 第 3 篇:栈、队列和数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

  • 本文基础知识部分来自于b站:分享笔记的好人儿的思维导图与王道考研课程,感谢大佬的开源精神,习题来自老师划的重点以及考研真题。
  • 此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析,本人技术有限,最终数据清洗结果不够理想,相关CSDN文章便没有发出。

(考研真题待更新)

欢迎订阅专栏:408直通车

请注意,本文中的部分内容来自网络搜集和个人实践,如有任何错误,请随时向我们提出批评和指正。本文仅供学习和交流使用,不涉及任何商业目的。如果因本文内容引发版权或侵权问题,请通过私信告知我们,我们将立即予以删除。

文章目录

  • 前言
  • 第三章 栈、队列和数组
      • 栈的概念
      • 栈的实现
        • 顺序栈
          • S.top == 0
        • 共享栈
        • 链栈
    • 队列
      • 队列的概念
      • 队列的实现
        • 队列的顺序存储结构
          • rear指向队尾元素
        • 队列的链式存储结构
        • 小结
      • 双端队列(挺喜欢考的考点)
      • 栈和队列有相同逻辑结构,线性结构
      • 合适与不合适做链队的链表,关键看能不能获取到首尾指针(带首尾的非循环或带尾的循环)
    • 栈和队列的应用
      • 栈的应用
        • 括号
        • 表达式求值
          • 中缀表达式转后缀表达式
          • 后缀表达式的计算
          • 中缀表达式转前缀表达式
          • 前缀表达式的计算
          • 中缀表达式的计算(用栈实现)
          • 其他
          • 小结
        • 递归
        • 小结
      • 队列的应用
    • 数组和特殊矩阵
      • 本节的题目计算都可以不记公式,直接代入推导
      • 数组
      • 特殊矩阵
    • 补充代码
      • 栈(数组模拟)
      • (循环)队列(数组模拟)
      • 单调栈
      • 单调队列
  • 考研真题
    • 408 - 2023

第三章 栈、队列和数组

在这里插入图片描述

栈的概念

  • 在这里插入图片描述

    • 限定仅在一端进行插入和删除操作的线性表,又称后进先出(LIFO)的线性表;
      允许插入删除的那一端叫栈顶(Top),不允许插入和删除的一端叫栈底(Bottom)

      • 特殊的线性表,后进先出(LIFO)在这里插入图片描述
    • 注意:n个不同元素进栈,出栈元素不同排序个数为(n个元素能构成多少种不同的二叉树)

    • 在这里插入图片描述
      在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

栈的实现

顺序栈
  • 栈的顺序存储结构

    • 顺序栈的基本结构在这里插入图片描述

      • 在这里插入图片描述

        • 利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时设一个栈顶指针(Top)

        • 基础结构在这里插入图片描述

          • 栈顶指针,初始值:S.top = -1(若有元素,则指向栈顶元素S.data[S.top])在这里插入图片描述

          • 进栈:栈不满时,栈指针先+1,再送值到栈顶在这里插入图片描述

            • 出栈:栈非空时,先取栈顶元素值,再将栈顶指针-1在这里插入图片描述
          • 栈空条件:S.top == -1

            • 栈满条件:S.top == MaxSize-1

              • 栈长:S.top + 1
    • 顺序栈的基本操作

      • 初始化、判栈空、进栈、出栈、读栈顶元素(本质就是操作顺序表)在这里插入图片描述
S.top == 0

在这里插入图片描述
在这里插入图片描述

共享栈
  • 共享栈
    • 在这里插入图片描述
      在这里插入图片描述

    • 概念

      • 让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸
    • 原则

      • 栈空判断:top0 = -1时0号栈为空,top1 = MaxSize时1号栈为空

      • 栈满判断:两个栈顶指针相邻(即top1-top0 == 1)时

      • 其他操作和顺序栈类似
        在这里插入图片描述

链栈

在这里插入图片描述

  • 栈的链式存储结构

  • 在这里插入图片描述

  • 采用单链表实现,并规定所有操作都是在单链表的表头进行在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 优点

    • 便于多个栈共享存储空间和提高效率,不存在栈满上溢的情况

队列

队列的概念

  • 在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    • 是一种操作受限的线性表,只允许在表的一端进行插入(队尾),另一端进行删除(队头)

      • 特殊的线性表,先进先出(FIFO)
    • 队头:删除元素的一端

      • 队尾:插入元素的一端
        在这里插入图片描述

队列的实现

队列的顺序存储结构
  • 队列的顺序存储结构
    • 在这里插入图片描述

      • 分配一块连续的存储单元存放队列元素,设两个指针

        • 队头指针front:指向队头元素
          队尾指针rear:指向队尾元素的下一个元素
      • 基础结构在这里插入图片描述

        • 初始状态(队空条件):Q.front == Q.rear == 0
          在这里插入图片描述

        • 进队操作:队不满时,先送值到队尾元素,再将队尾指针+1在这里插入图片描述
          在这里插入图片描述

        • 出队操作:队不空时,先取队头元素值,再将队头指针+1

      • 假溢出:在data数组依然存在空位置时,却已经满足队列满的条件(出栈的元素位置空闲)

    • 循环队列(解决假溢出问题)

      • 在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述

        • 概念

          • 把存储队列元素的表逻辑上视为一个环
        • 基本操作

          • 初始时:Q.front = Q.rear = 0

          • 队头指针+1:Q.front = (Q.front + 1) % MaxSize

          • 队尾指针+1:Q.rear = (Q.rear + 1) % MaxSize

          • 队列长度:(Q.rear + MaxSize - Q.front) % MaxSize

          • 队空:Q.front == Q.rear

        • 队满判断

          • 牺牲一个单元来区分队空和队满,即队头指针在队尾指针的下一位置作为队满标志在这里插入图片描述

            • 队满条件:(Q.rear + 1) % MaxSize == Q.front
          • 类型中增设表示元素个数的数据成员(int size)在这里插入图片描述

            • 队空:Q.size == 0

            • 队满:Q.size == MaxSize

          • 类型中增设tag数据成员,以区分是队满还是队空在这里插入图片描述

            • tag == 0时,若因删除导致Q.front == Q.rear,则队空

            • tag == 1时,若因插入导致Q.front == Q.rear,则队满

rear指向队尾元素

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
牺牲一个存储单元

  1. front在rear后两个位置,队满
  2. front在rear后一个位置,队满
    在这里插入图片描述
队列的链式存储结构
  • 队列的链式存储结构在这里插入图片描述
    • 在这里插入图片描述

      • 队列的链式表示时一个同时带有队头指针和队尾指针的单链表

      • 头指针指向队头结点,队尾指针指向队尾结点,当Q.front == NULL且Q.rear == NULL时,队列为空在这里插入图片描述
        在这里插入图片描述

      • 不存在队列满且溢出问题,适合于数据元素变动较大的情况在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结

在这里插入图片描述

双端队列(挺喜欢考的考点)

  • 概念

    • 双端队列是指允许两端都可以进行入队和出队操作的队列,其逻辑结构仍是线性表在这里插入图片描述
  • 分类在这里插入图片描述

    • 输出受限的双端队列:允许在一端进行插入和删除,但在另一端只允许插入的双端队列

    • 输入受限的双端队列:允许在一端进行插入和删除,但在另一端只允许删除的双端队列

栈和队列有相同逻辑结构,线性结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

合适与不合适做链队的链表,关键看能不能获取到首尾指针(带首尾的非循环或带尾的循环)

  • 单链表实现队列,队头只能设置在链头(关注删除操作,需找到新队头)

栈和队列的应用

栈的应用

括号
  • 括号匹配在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    • 步骤

      • 初始设置一个空栈,顺序读入括号

      • 若右括号,则从栈中弹出一个符号,判断是否匹配

      • 若左括号,则压入栈中

    • 失败条件

      • 不匹配、结束后栈仍有元素、遇右括号栈为空
表达式求值

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

中缀表达式转后缀表达式
  • 从左到右遍历各元素

    • 若遇到操作数:直接加入后缀表达式

    • 遇到界限符:“(”直接入栈;“)”则依次弹出栈内运算符并加入后缀表达式,直到弹出“(”为止

    • 遇到运算符:依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止,之后再把运算符入栈
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后缀表达式的计算
  • 从左向右扫描元素,若扫描到操作数则压入栈,若扫描到运算符则弹出两个栈顶元素,执行运算将结构压回栈中
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

中缀表达式转前缀表达式
  • 同理但从右到左遍历,“(”和“)”与中缀转后缀的功能相反,最后结果依次翻转

在这里插入图片描述
在这里插入图片描述

前缀表达式的计算
  • 从右向左扫描元素,若扫描到操作数则压入栈,若扫描到运算符则弹出两个栈顶元素,执行运算将结构压回栈中

在这里插入图片描述
在这里插入图片描述

中缀表达式的计算(用栈实现)
  • 初始化操作数栈和运算符栈

  • 若扫描到操作数,压入操作数栈;若扫描到运算符或界限符,按“中缀转后缀”的逻辑压入运算符栈(可能弹出运算符,若弹出则将栈顶的两个操作数运算压回操作数栈)
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

其他
  • 其他:数制转换、八皇后问题、行编辑程序、函数调用、迷宫求解等
小结

在这里插入图片描述

递归

在这里插入图片描述

在这里插入图片描述

  • 概念

    • 若对象部分地包含自己,或用自己给自己定义,则称这个对象是递归的

    • 若一个过程直接或间接的调用自己,则这个过程是递归的

  • 分治的思想:必备条件

    • 能将一个问题转变成一个新问题,且两者的解法相同或类似,不同的仅是对象,且对象有变化规律

    • 可以通过上述转化将问题化简

    • 必须有一个明确的递归出口(递归边界)

  • 形式

    • 在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

在这里插入图片描述

小结

在这里插入图片描述

队列的应用

  • 脱机打印输出、解决多用户引起的资源竞争问题、广度优先遍历、网络电文传输按时间先后顺序依次进行等等

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数组和特殊矩阵

在这里插入图片描述

本节的题目计算都可以不记公式,直接代入推导

数组

  • 概念

    • 数组是由n个相同类型的数据元素构成的有限序列,每个元素在n个线性关系中的序号称为元素下标,下标取值范围称为数组的维界
  • 与线性表的关系

    • 数组是线性表的推广,一维数组可视为一个线性表,二维数组可以视为其元素也是定长线性表的线性表
  • 数组的存储结构

    • 数组的所有元素在内存中占用一段连续的存储空间

    • 一维数组在这里插入图片描述

      • 存储结构关系式:LOC(ai) = LOC(a0) + i × L (0 <= i < n,L是每个元素所占存储单元)
    • 多维数组在这里插入图片描述

      • 按行优先(一行行存储)

        • 存储结构关系式:LOC(ai,j) = LOC(a0,0) + [i × (h1 + l) + j] × L (二维数组:h1 × h2)在这里插入图片描述
      • 按列优先(一列列存储)

        • 存储结构关系式:LOC(ai,j) = LOC(a0,0) + [j × (h2 + l) + i] × L (二维数组:h1 × h2)在这里插入图片描述

特殊矩阵

  • 指具有许多相同矩阵元素或0元素,并且这些相同矩阵元素或0元素的分布有一定规律

  • 压缩矩阵

    • 找出特殊矩阵中值相同的矩阵元素的分布规律,把那些呈现分布规律的、多个值相同的元素只分配一个存储空间,对0元素不分配空间在这里插入图片描述
  • 对称矩阵

    • 概念

      • 若对一个n阶方阵中的任意元素a(i, j) = a(j, i),则称其为对称矩阵,可放在一维数组B[n(n+1)/2]中在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
    • 存储位置计算公式在这里插入图片描述

  • 三角矩阵

    • 概念

      • (上/下)三角区的所有元素均为同一常量,其可压缩为存储完(下/上)三角区和主对角线上元素 + 存储常量一次
    • (下/上)三角矩阵元素下标对应关系

      • 下三角矩阵在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述

      • 上三角矩阵在这里插入图片描述

    • (下/上)三角矩阵在内存中的压缩存储形式

      • 下三角矩阵在这里插入图片描述

      • 上三角矩阵在这里插入图片描述

  • 三对角矩阵

    • 在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

      • 概念

        • 又称带状矩阵,除以对角线为中心的3条对角线区域外都为0
      • 压缩存储:将元素按行优先方式存放在一维数组B中,且a(i, j)与B[n]对应关系为:k = 2i + j - 3

  • 稀疏矩阵在这里插入图片描述

    • 概念

      • 矩阵中非0元素的个数t,相对矩阵元素的个数s来说非常少,即s>>t
    • 存储方式

      • 三元组(行标、列标、值)
        在这里插入图片描述

      • 十字链表法 在这里插入图片描述

    • 稀疏矩阵压缩存储后失去了随机存取的特性
      在这里插入图片描述
      在这里插入图片描述

补充代码

栈(数组模拟)

  • 对数组简单操作,略

(循环)队列(数组模拟)

  • 循环队列注意点:队满与队空条件需要有区别,即需要一个额外的元素空间判断队空与队满

void push_q(int x){if((tail + N + 1) % N != head){  //判断队满q[tail] = x;tail = (N + tail + 1) % N;  //队尾插入一个数据注意指针移动需要%N,对头类似:head=(N+head+1)%N;}
}
bool empty(){  //判断是否为空return head == tail;
}
void pop_q(){  //对头删去一个元素if(!empty())head = (N + head + 1) % N;
}
void query(){  //查询对头元素if(!empty())printf("%d\n",q[head]);
}

单调栈

  • 应用场景:求某个数左边第一个小于他的数;
    思路:在每次暴力从for循环的当前值,向左遍历找第一个小于数的O(n2)情况下进行优化;
    在向左遍历过程中删去无用的数(左边小于,但值大于),利用栈形成单调增大的序列,所求数即为栈顶;

  •   for(int i=0;i<n;i++){scanf("%d",&v);while(top&&s[top-1]>=v) top--;           //去除比当前数大但在左边的数if(!top) printf("-1 ");else printf("%d ",s[top-1]);                    //输出栈顶元素,即第一个小于当前数的数s[top++]=v;                                          //当前数压入栈中}
    

单调队列

  • 应用场景:滑动窗口中最小值,也可优化背包问题;
    思路:同理通过删去无用的数进行优化;
    (求滑动窗口中最小值)队列头保留最小的数,遍历数组,若队尾数大于遍历的数则不断删去队尾(同理无用的数),使得队列单调增,在遍历过程中,不断更新队头使得不超过滑动窗口。

  • for(int i=0;i<n;i++){if(l<r&&i-q[l]>len-1) l++;                       //移动对头使不超过滑动窗口,为了实现,q数组存下标while(l<r&&v[q[r-1]]>=v[i]) r--;              //弹出队尾无用数,因为会在队尾弹出不满足先进先出原则,事实上也不能叫单调队列q[r++]=i;                                                  //每次都入队一个if(i>=len-1) printf("%d ",v[q[l]]);
    }
    

考研真题

408 - 2023

(考研真题待更新)

这篇关于【数据结构】考研真题攻克与重点知识点剖析 - 第 3 篇:栈、队列和数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/880359

相关文章

嵌入式软件工程师应聘知识点

嵌入式软件工程师应聘 修改浏览权限 | 删除 数据结构(C语言)部分常考的知识点: 1、局部变量能、全局变量和静态变量 2、堆和栈 3、Const、volatile、define、typedef的用途 4、链表(比如链表的插入、删除和排序) 5、排序(考查冒泡法的较多) 6、可重入函数 、malloc函数 7、指针(常考函数指针,函数指针,数组指针,指针数组和

数据库期末复习知识点

A卷 1. 选择题(30') 2. 判断范式(10') 判断到第三范式 3. 程序填空(20') 4. 分析填空(15') 5. 写SQL(25') 5'一题 恶性 B卷 1. 单选(30') 2. 填空 (20') 3. 程序填空(20') 4. 写SQL(30') 知识点 第一章 数据库管理系统(DBMS)  主要功能 数据定义功能 (DDL, 数据定义语

【数据结构】线性表:顺序表

文章目录 1. 线性表2. 顺序表2.1 概念及结构2.2 接口实现2.3 顺序表的问题及思考 1. 线性表 线性表是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式

数据结构9——排序

一、冒泡排序 冒泡排序(Bubble Sort),顾名思义,就是指越小的元素会经由交换慢慢“浮”到数列的顶端。 算法原理 从左到右,依次比较相邻的元素大小,更大的元素交换到右边;从第一组相邻元素比较到最后一组相邻元素,这一步结束最后一个元素必然是参与比较的元素中最大的元素;按照大的居右原则,重新从左到后比较,前一轮中得到的最后一个元素不参4与比较,得出新一轮的最大元素;按照上述规则,每一轮结

剑指offer(C++)--数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 class Solution {public:void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {int len = data.size();if(len<2)return;int one = 0;for(int i

3月份目标——刷完乙级真题

https://www.patest.cn/contests/pat-b-practisePAT (Basic Level) Practice (中文) 标号标题通过提交通过率1001害死人不偿命的(3n+1)猜想 (15)31858792260.41002写出这个数 (20)21702664840.331003我要通过!(20)11071447060.251004成绩排名 (20)159644

IOS 数组去重的几种方式

本来只知道NSSet和KeyValues的。今天又新学了几种方式 还有就是和同事学的一种方式 外层循环从0开始遍历,内层从最后一个元素开始遍历 for(int i=0;i<index;i++){  for(int j=index-1;j>i;j-- ){ } }

算法与数据结构面试宝典——回溯算法详解(C#,C++)

文章目录 1. 回溯算法的定义及应用场景2. 回溯算法的基本思想3. 递推关系式与回溯算法的建立4. 状态转移方法5. 边界条件与结束条件6. 算法的具体实现过程7. 回溯算法在C#,C++中的实际应用案例C#示例C++示例 8. 总结回溯算法的主要特点与应用价值 回溯算法是一种通过尝试各种可能的组合来找到所有解的算法。这种算法通常用于解决组合问题,如排列、组合、棋盘游

嵌入式学习——数据结构(哈希、排序)——day50

1. 查找二叉树、搜索二叉树、平衡二叉树 2. 哈希表——人的身份证——哈希函数 3. 哈希冲突、哈希矛盾 4. 哈希代码 4.1 创建哈希表 4.2  5. 算法设计 5.1 正确性 5.2 可读性(高内聚、低耦合) 5.3 健壮性 5.4 高效率(时间复杂度)时间复杂度越低,效率越高, 5.5 低储存(空间复杂度)空间复杂度越低,存储空间越少 6.排序算法 6.1 冒

【数据结构与算法 经典例题】使用队列实现栈(图文详解)

💓 博客主页:倔强的石头的CSDN主页               📝Gitee主页:倔强的石头的gitee主页    ⏩ 文章专栏:《数据结构与算法 经典例题》C语言                                   期待您的关注 ​​ 目录  一、问题描述 二、前置知识 三、解题思路 四、C语言实现代码 🍃队列实现代码: