补充:
- 7.22 B-树、B树和B+树
- 7.23 决策表(判断表)、符号表、广义表(列表)、索引表
7.01 数据结构与算法基础
7.02 数组
掌握:
- 存储地址的计算
- 二维数组当中
按行存储
和按列存储
的区别
7.03 稀疏矩阵
考察:
计算稀疏矩阵当中某一个元素它对应的一维数组的下标
稀疏矩阵的概念:
- 官方:在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵
- 简单理解:一个矩阵当中,所记录的元素,如果说大量的元素都是零的话,称之为~
注:图中的无向图,存下来就是一个三角矩阵
解题思路:
- 背公式
- 代入法
代入法例题:
- 带入A(0,0),结果应该是M[1]
- 注:因为M数组从1开始
- 分别带入下面几个选项如果M≠1则选项为错
- 带入A(1,1),结果应该是M[3]
- 注:也记住下标计算公式进行演算
例题讲解【2021上】
- 三元组顺序表和十字链表
7.04 数据结构的定义
数据结构:
就是计算机存储以及组织数据的方式
研究意义:
选择不同的数据结构,可能带来的运行效率差距会非常大
数据结构从逻辑层面来分:
- 线性结构
- 非线性结构
- 树(没有环路)
- 图(可能存在环路)
数据结构从存储结构层面来分:
注:
广义的图包括(线性结构、树)
广义的树包括(线性结构)
7.05 顺序表与链表
- 注:引入头节点可以令所有的节点操作方式变成一致的
- 如果头节点中放了具体的内容,则头节点的处理要用不同的处理方式
7.06 顺序存储与链式存储
7.07 队列与栈
队列(包括循环队列)与栈的基本介绍
循环队列
概念:
- 指采用顺序存储结构实现的队列。
- 在顺序队列中,为了降低运算的复杂度,元素入队时,只修改队尾指针: 元素出队时, 只修改队头指针。由于顺序队列的存储空间是提前设定的,因此队尾指针会有个上限值,当队尾指针达到其上限时,就不能只通过修改队尾指针来实现新元素的入队操作了。
- 此时,可将顺序队列假想成一个环状结构,称之为循环队列,同时保持运算的简便性。
- 将元素存储在一维数组中的队列假想成一个环状结构,称为循环队列。
循环队列优点:
- 可以有效的利用资源。用数组实现队列时,如果不移动,随着数据的不断读写,会出现假满队列的情况。即尾数组已满但头数组还是空的;
- 循环队列也是一种数组,只是它在逻辑上把数组的头和尾相连,形成循环队列,当数组尾满的时候,要判断数组头是否为空,不为空继续存放数据。
- 入队和出队操作都不需要移动队列中的其他元素
循环队列缺点:
- 循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"是"满"。
循环队列补充知识:
- 为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列。
步骤:
- 存一个数据:尾指针向后移动一位
- 从队列中出去一个元素的时候:头指针向后移动一位
循环队列这样会出现的问题,队满的时候头和尾指针又指向到一起
解决方案:
- 记录当前到底是队满还是队空(了解即可,麻烦)
- 在这些元素里面,空间里面少存一个元素
- 比如5个空间只存4个元素
例题讲解【2021下】
考察:
- 循环队列
栈与队列的组合使用
所以实际上,以某种顺序入栈,可以得到的出栈序列情况是多种多样的
双向栈的概念
特点:
- 数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下标为数组长度M-1处。这样,两个栈如果增加元素,就会从两端点向中间延伸(如下图)。
概念:
- 在连续的数据空间内两个栈增长时栈顶标志的移动方向是相反的,所以当栈1的顶和栈2的顶邻接(top[1]+1=top[2])的时候不再有剩余空间,栈满。
例题讲解【2021下】
考察:双向栈
- 选B
- 解析:
- 意题目:栈 1 的底在 V[1] ,栈 2 的底在 V[m]
- 这道题其实是想考察双向栈的概念。在连续的数据空间内两个栈增长时栈顶标志的移动方向是相反的,所以当栈1的顶和栈2的顶邻接(top[1]+1=top[2])的时候不再有剩余空间,栈满。
例题讲解【2021上】
考察:栈
例题(栈与队列的结合)
分析:
看最终要输出的序列,在队列当中的排列情况,再看入队的时候有没有可以形成这种结果
例题(栈与队列的结合):答案
分析:选项A
分析:选项B
分析:选项C
分析:选项D
- 答案:D
7.08 广义表
定义
是n个元素组成的有限序列,是线性表的推广
例题
- 例2解题思路:通过取表头和表尾的嵌套操作
长度和深度的求法:答案
长度:最外层元素的个数
- 元素分:表元素和子表
深度:就是嵌套的次数
两种基本的运算~~取表头head(Ls)和取表尾tail(Ls):答案
表头:最外层的第一个表元素
表尾:除了第一个元素以外的其他所有元素,所组成的广义表
7.09 树与二叉树的基本概念
根结点:父节点的结点(最上面的结点)
叶子结点:没有孩子结点的结点
结点的度:一个结点它拥有的孩子节点数
树的度:在一个树当中它的结点度数最高的呢个【本题:2】
叶子结点:没有孩子结点的都称为
分支结点:分支结点指的是度不为0 的结点
内部结点:既非叶子结点也非根结点
父结点和子结点:是一个相对的概念
兄弟结点:同一个父亲低下,平级的结点
层次:一层一层的结点表示方式
7.10 满二叉树和完全二叉树
满二叉树:
整棵树,没有缺失的结点
完全二叉树:
除了最底下一层,上面的层次都是满的,而底下的结点是从左到右来排列的
例题讲解【2021上】
- 排序二叉树:根结点的左子树都要小于根结点,右子树的结点都要比根结点大
- 完全二叉树:除了最底下一层,上面的层次都是满的,而底下的结点是从左到右来排列的
- 线索二叉树【前序线索二叉树为例】:先根据前序将二叉树进行排序,然后叶子结点左子树的指针指向前序遍历的前趋结点,而叶子结点右子树的指针指向前序遍历的后继结点
- 最优二叉树【哈夫曼树】:让一颗树的带权路径长度是最短的情况。
例题讲解【2021下】
考察:二叉树的特性:
- 满二叉树的节点10层是2的10次方减1共计1023,所以1024个节点得需要11层
二叉树的特性
1,2,3的特性
4-1特性
4-2特性
- i是按层序的编号
- n是这棵树的结点总数
4-3特性
总结:满二叉树和完全二叉树这种按层次的方式进行排列能很好的提高效率。
7.11 二叉树遍历
遍历分类:
一:区分:前中后通过根节点什么时候访问来区分
前序遍历:12457836
中序遍历:42785136
后序遍历:48752631
二:层次遍历
- 按层遍历:12345678
7.12 反向构造二叉树【根据给出的序列推导出二叉树或者另一个序列】
定义:我们知道二叉树的遍历序列,然后反向推出这个二叉树是一个什么情况
题型:根据给出的序列推导出二叉树或者另一个序列
- 前中序,中后序都可以推出二叉树;但是前后序不能推出二叉树。
具体案例:
结果展示:
7.13 树转二叉树
一、一般的方法:利用基本原则
树转二叉树的基本原则:配合使用
- 在树当中,一个结点的孩子结点,都会成为这个结点的左子树结点。
- 某个结点的兄弟兄弟结点,都会成为这个树的右子树(右孩子)结点。
二、简单的方法:连线法【考试推荐】
使用方法:
- 对于兄弟结点,用线连起来
- 对于多个孩子结点,只保留第一条线
- 最后将树做一下旋转
7.14 二叉查找树(二叉排序树、二叉搜索树、二叉检索树,二叉排序树)
查找二叉树的特性:特殊的二叉树,根结点的左子树都要小于根结点,右子树的结点都要比根结点大。——这种符合上面特性的树称为:
这种树的意义(优势):提高查询的速度
7.15 最优二叉树(哈夫曼树)
掌握:
基本概念和会计算树的带权路径长度
前言:
这种树是一种工具,用于哈夫曼编码
哈夫曼编码是一种压缩编码方式,可以让原始信息的编码长度变得更短,从而节省存储空间和传输带宽。——一种无损压缩方式
基本概念:
树的路径长度:树当中的路径,累加起来的长度
权:某个叶子结点
,它有一个数值,这个数值代表了某一种字符出现的频度
- 相对来说,俩叶子结点上面的父结点就是孩子结点权值的汇合,比如15,14,12
带权路径长度:路径的长度(根到该权值的路径) * 权值
例子:
到2号结点的带权路径长度为:22=4
到4号结点的带权路径长度为:34=12
树的带权路径长度(树的代价):把所有带权路径长度累加起来就是整棵树的
构造一棵哈夫曼树基本思想与理念:
要达到一个效果,就是让一颗树的带权路径长度是最短的情况。
如何构造:
- 先找到一组权值中最小的两个权值,组成一颗小树
- 将这组权值中呢两个权值删除,替换成汇合的权值
- 同1步骤再找两个最小的权值,组成一颗小树(如果其中某权值为上一步两权值之和,就进行链接,否则组成一颗新的小树)
- 以此类推
得到哈夫曼树之后,求整棵树的带权路径长度:将每个叶子结点的带权路径长度求出来之后进行累加。
- 为什么只算叶子结点的:因为这些才是初始的权值,其他的中间结点都是我们构造出来的结果。
例题讲解【2021下】
- 考察:从小到大按词频先排序,然后从底向上构造树。所有字符都是叶子节点,按照左小右大的原则构造
- 哈夫曼编码构造过程
例题讲解【2017下】
7.16 线索二叉树
为什么要有线索二叉树:
将二叉树叶子结点空闲的资源利用起来,主要利用起来做遍历操作。
如何转换为线索二叉树:【以前序线索二叉树为例】
先根据前序将二叉树进行排序,然后叶子结点左子树的指针指向前序遍历的前趋结点,而叶子结点右子树的指针指向前序遍历的后继结点
7.17 平衡二叉树
平衡二叉树提出的原因:因为排序二叉树(左子树恒小于根结点,右子树恒大于根结点),同样的序列可能有多颗树,其中一些比较偏不平衡,效率就会很低。
- 排序二叉树越平衡,查找效率越高。
平衡二叉树的定义:【每一层子树都要达到要求】
- 平衡度的求法:左子树的深度减右子树的深度
- 比如权值为7的平衡度:2-2=0
- 比如权值为3的平衡度:3-0=3
调整不平衡的排序二叉树:
- 把相应的数折过来
图的概念【了解即可】
7.18 图的概念及存储【了解】
考试内容少——了解即可
邻接矩阵
- 对于无向图的邻接矩阵来说,可以对角线对折,所以为了节省存储空间,可以只存上三角或下三角。
补充:【原文链接】
无向图的邻接矩阵表示法
- 分析1:无向图的邻接矩阵是对称的;
- 分析2:顶点i的度=第i行(列)中1的个数;
- 特别:完全图的邻接矩阵中,对角元素为0,其余1。
有向图的邻接矩阵表示法
- 注:在有向图的邻接矩阵中,
- 第i行含义:以结点vi为尾的弧(即出度边);
- 第i列含义:以结点vi为头的弧(即入度边)。
- 分析1:有向图的邻接矩阵可能是不对称的;
- 分析2:顶点的出度 = 第 i 行元素之和
- 顶点的入度 = 第 i 列元素之和
- 顶点的度 = 第 i 行元素之和 + 第 i 列元素之和
有权图(网)的邻接矩阵表示法
邻接表
领接表的方式:用一个数组来记录各个结点的,再用链表来记录每个结点可以到的顶点情况。
7.19 图的遍历
- 上图实例不知道存储的结构是如何的
下面结合存储的结构来看
广度优化:
深度优化:
7.20 拓扑排序
关系:用一个序列来表达一个图当中,那些事件可以先执行,那些事件可以后执行。
一般考题是看那个不是有向图的拓扑排序
- 从约束的角度来看,如图3收到4的约束,则只能先4再3
一、什么是拓扑排序【引用:原文】
在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:
- 每个顶点出现且只出现一次。
- 若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。
有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。
例如,下面这个图:
它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:
- 从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
- 从图中删除该顶点和所有以它为起点的有向边。
- 重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。
于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。
通常,一个有向无环图可以有一个或多个拓扑排序序列。
二、拓扑排序的应用
拓扑排序通常用来“排序”具有依赖关系的任务。
比如,如果用一个DAG图来表示一个工程,其中每个顶点表示工程中的一个任务,用有向边 表示在做任务 B 之前必须先完成任务 A。故在这个工程中,任意两个任务要么具有确定的先后关系,要么是没有关系,绝对不存在互相矛盾的关系(即环路)。
例题讲解【2021下】
- C
- 拓扑序列是拓扑排序的产出物。对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。由此可见,如果Vi排列在Vj之前,说明可能存在vi到vj的路径,而不可能存在vj到vi的路径。
7.21 图的最小生成树(普里姆算法)
概念:就是把图当中很多的线和边去掉,留下若干条表,将所有结点连贯起来
- 留下来的一部分,加起来权值最小。
图的最小生成树流程:
- 树的结点是n,则边为n-1
- 则在结点是n的图当中选出n-1个边,才能构成树
有两种算法可以解决这类问题:
- 普里姆算法
- 克鲁斯卡尔算法
普里姆算法
普里姆算法步骤:
- 先确定要选5条最短的边
- 在图中选任意一个结点为红点集,其他结点为蓝点集
- 找到红点集到蓝点集最小距离的边
- 红点集和边连线的蓝点集也变成了红点集
- 找到两个红点集到蓝点集最小距离的边
- 以此类推
普里姆算法注意点:
- 选出来的线是最初所有线里最短的五条线
- 选的边有一个原则:不能够形成环
- 只能红点集找蓝点集
克鲁斯卡尔算法
克鲁斯卡尔算法步骤:
- 先确定要选5条最短的边
- 然后从最短的边开始选起,随后升序选边
- 选边过程中不能形成环路
- 此题中:先选100的,然后选两条200的,再选250的,300的一个边能成环路不选,最后选400的
7.22 B-树、B树和B+树
7.23 决策表(判断表)、符号表、广义表(列表)、索引表
- 决策表又称【判断表】
- 是一种呈表格状的图形工具,适用于描述处理判断条件较多,各条件又相互组合、有多种决策方案的情况。
- 符号表
- 在编译程序工作的过程中需要不断收集,记录和使用源程序中一些语法符号的类型和特征等相关信息。这些信息一般以表格形式存储于系统中。
- 广义表,又称【列表】
- 也是一种线性存储结构。通常,广义表中存储的单个元素称为 “原子",而存储的广义表称为“子表"
- 索引表
- 是一张指示逻辑记录和物理记录之间对应关系的表。索引表中的每项索引项按键(或逻辑记录号)顺序排列。在索引顺序文件中,可对一组记录建立一个索引项。