408复习笔记(二):经典数据结构和算法PART2(图、查找、排序)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

接前文
408复习笔记(一):经典数据结构和算法PART1(线性表、栈和队列、数组和特殊矩阵、串、树)

六、图

1.一些定义

注:线性表可以是空表,树可以是空树,但图不能是空图。图的顶点集V一定不为空,边集E可以为空,此时图中只有顶点没有边。
①简单图:不存在重复边且不存在顶点到自身的边的图
②完全图:任意两个顶点之间都有边(如果是有向图完全图,任意两个顶点之间都有相反的两条边)【也就是边数最多的简单图】
③子图:子图的顶点集和边集都是原图的子集,如果只有边集是真子集,顶点集相等,那称为生成子图
在这里插入图片描述
④连通图(强联通图):一般在无向图中讨论连通性,在有向图中讨论强连通性
两个顶点间:无向图中,如果两个顶点之间有路径,则称他们是连通的;有向图中,两个顶点间来和往都有路径,称他们是强联通的
一个图:如果无向图(有向图)任意两个顶点之间都是连通(强连通)的,那称这个图为连通图(强联通图)
PS:无向图极大连通子图称为连通分量有向图极大连通子图称为强连通分量。极大要求该连通子图包括所有的边
⑤生成树(生成森林):
连通图的生成树是包含图中所有顶点的极小连通子图(极小意为边数最少),n个顶点的图,其生成树一定有n-1条边;在非连通图中,其连通分量的生成树组成了生成森林。
⑥网(带权图):边上带有权值的图叫做带权图,也叫网
⑦字太多不想打了
在这里插入图片描述

2.图的存储

①邻接矩阵法:一个二维表格,下标代表结点号,值代表边的情况
无向图中有边是1,无边是0,对角线对称;有向图中也是这样,但对角线不对称;带权图中值是权值,注意空的地方用无穷填满!
②邻接表法(适用于稀疏图):一个数组记录每个顶点,每个顶点的记录指针指向跟此顶点有边的顶点,并形成一个单链表
这个单链表是该顶点的边表(有向图中叫做‘出边表’)
在这里插入图片描述
=7.28日更新==

③十字链表:有向图的链式存储结构
含义:所有依附于同一顶点的边串联在同一个链表中,每条边依附于两个顶点,因此每个边结点同时在两个链表中(一个链表为这些边的出点相同,另一个为入点相同),因此在每个边结点处形成十字。

1.画邻接表(结点):(顶点表结点【顶点,指向相同变表结点,指向本行下一个结点】和边表结点【此边头,此边尾,同尾,同头】)
2.增加弧节点的域(本行内指针)
3.自己指向自己(左到右依次标号相同的指)
【数据结构|十字链表|简单粗暴零失误画出十字链表-哔哩哔哩】 https://b23.tv/8g1fTUs
eg:
在这里插入图片描述

④邻接多重表:无向图的链式存储结构
1.造结点(顶点表结点【data,标号】,边表结点【此边头,空,此边尾,空】)同一个边只有一个边结点,写在哪个顶点后都可以
2.把前两个看成一家,后两个看成一家,找相同画指针就完事(左右不分)
【邻接多重表-哔哩哔哩】 https://b23.tv/whOcvCT
这个图我知道它丑,但我真的不想改了QAQ
在这里插入图片描述

=7.30日更新==

3.图的遍历(BFS、DFS)

一次调用只能遍历一个连通分量
可能会考察BFS或DFS遍历时的生成子树或者遍历序列,从不同的顶点出发,结果也不同

4.最小生成树

最小:权值最小;生成树:找齐n-1条边。即:求能使各个结点连接起来的最小代价问题

1)Prim(point,点)

①任意取一个点,找与它连接的边中最小的一个加入,然后把已有的两个点看做整体,再去找周围最小的一个边加入。
②每次寻找当前权值最小的边加入,直至找够n-1条边
在这里插入图片描述

2)Kruskal(边)

从小到大依次找边,如果某边的两点不连通,将此边加入,如果连通,将此边舍弃。
在这里插入图片描述

5.最短路径算法

1)Dijkstra

①贪心算法
②一次调用只能求出图中某一个顶点到其他所有顶点的最短路径(单源最短路径)
③只能算权重非负,但效率高
https://www.bilibili.com/video/BV1zz4y1m7Nq?spm_id_from=333.337.search-card.all.click&vd_source=004a97c60ce7b19403906146d0b7240f
在这里插入图片描述

在这里插入图片描述

2)Floyd

①二维动态规划,核心代码相当于推dp状态方程,
②一次调用就可以求出图中任意两点间的最短路径,(多源最短路径)
https://www.bilibili.com/video/BV14R4y1x7GB/?spm_id_from=333.788.recommend_more_video.-1&vd_source=004a97c60ce7b19403906146d0b7240f

①画邻接矩阵(P-1)
②对于i=0、1、2…n-1,迭代矩阵(以i为中转点)
在这里插入图片描述

6.拓扑排序(AOV网)activity on vertex Network(顶点表示活动,有向边表示活动的前后关系)

①活动:用有向图来描述一项工程的实施过程,将一个工程分为多个子工程,即活动(Activity),
②AOV网:在有向图中以顶点表示活动,有向边表示活动之间的先后关系,这样的图简称为AOV网。
③拓扑排序:在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,此序列叫做拓扑序列。
④构造拓扑序列:每轮选择AOV网中一个入度为0的顶点并输出,然后删除该顶点和所有它为起点的有向边,输出的顶点序列为拓扑序列。
在这里插入图片描述

7.关键路径(AOE网)activity on edge Network(边表示活动,权值表示活动的开销)

①关键路径:从源点到汇点的所有路径中具有最大路径长度的一条;关键路径上的活动叫做关键活动
②应用:
在这里插入图片描述
https://www.bilibili.com/video/BV1EQ4y1v7iV?spm_id_from=333.337.search-card.all.click&vd_source=004a97c60ce7b19403906146d0b7240f

=8.1日更新==

七、查找

1.散列查找

1)散列表的构造

①直接定址法:H(key)=key 或 H(key)=a*key + b
②除留余数法:H(key)=key%p
③平方取中法:取关键字的平方值的中间几位作为散列地址

2)冲突处理方法

开放定址法:
①线性探测:每次冲突时依次向后探测下一个单元是否为空(d=0,1,2,3……)
②平方探测:每次冲突依次探测后,前的整数平方的位置(di=0^2 ,1^2, -1^2, 2^2, -2^2,…,k^2, -k^2时)
③伪随机序列法:d=某个随机序列
在这里插入图片描述

拉链法:散列表的每个单元存储一个链表头指针,把该单元所有同义词存储在这个线性链表中,查找、插入和删除操作主要在同义词链中进行。

3)查找成功和查找失败的平均查找长度

查找成功:sum(每个元素插入时查看的单元格数)/元素个数
查找失败:sum(每个单元格处向后到第一个空处,期间查看的单元格数)/单元格个数 【Ps:单元格空的算1次查看,即需要知道他为空】
例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4)散列查找的特征和性能分析

散列表的查找效率取决于三个因素:散列函数、处理冲突的方法和装填因子。
(假设散列表的空间大小为m,填入表中的元素个数为n,则=n/m称为散列表的装填因子。 一般设计为=0.5~0.8较好。)

2.折半查找

1)折半查找的过程

对于一个有序表,low指向表头元素,high指向表尾元素,mid=floor(low+high)。每轮判断target和mid的大小:
若target<mid,high=mid-1,重新计算mid;若target>mid,low=mid+1,重新计算mid;若相等,则已找到。
循环条件是low<=high(若一直没找到,倒数第二轮mid指针和low指针重合,最后一轮low和high指针重合)

2)构造判定树

中间结点是关键字(非叶节点),叶节点是方形的范围,代表查找不成功的情况
检验:对于n个数字的序列,判定树有n个非叶子节点和n+1个叶子节点

3)分析平均查找长度(ASL)

在这里插入图片描述

3、红黑树

红黑树是什么,有什么意义:
排序二叉树有不平衡的问题,可能左子树很长但是右子树很短,造成查询时性能不佳(logn退化成n),完全平衡的二叉树能保证层数平均,从而查询效率高,但是维护又很麻烦,每次插入和删除有很大的可能要大幅调整树结构。
红黑树就是介于完全不平衡和完全平衡之间的一种二叉树,通过每个节点有红黑两种颜色、从节点到任意叶子节点会经过相同数量的黑色节点等一系列规则,实现了【树的层数最大也只会有两倍的差距】,这样既能提高插入和删除的效率,又能让树相对平衡从而有还不错的查询效率。从整体上讲,红黑树就是一种中庸之道的二叉树

4、b树和b+树

1)b树(也是一种排序树)(平衡二叉树的扩展,平衡多叉树)
a.构建(插入)元素:

首先根据阶数找到最多可以容纳的关键字范围(根结点可以不受下限约束),然后就可以依次向树中添加元素了,必须在叶子节点上添加(下图中写错了但我不想改了QAQ)
【B-树的插入(创建)-哔哩哔哩】 https://b23.tv/rvio0tO
在这里插入图片描述

b.删除:

(1)如果是叶子结点:合适直接删除,不合适找根或兄弟替补(最后可以再插入,求逆过程验证删除是否正确)
“合适”是指b树的性质:
①b树孩子节点的个数等于该结点中的关键字个数加一
②节点中关键字从左到右递增有序
③指针所指向子树的关键字一定落在其父节点关键字所划分的区间内

(2)如果删除根结点,需要用其左子树最大或右子树最小元素进行替换(中序遍历的前驱或后继元素),然后删除此叶子结点

c.查找

b树中大部分操作所需的磁盘存取次数与b树的高度成正比

在这里插入图片描述

2)b+树:基本概念与性质

在这里插入图片描述
=8.2日~8.3日更新==

八、排序

1.基本概念

①排序算法是稳定的:两个关键字相同的元素经排序后先后顺序不变
②内部排序:排序期间元素全部存放在内存中;外部排序:排序期间元素需要在内存和外存之间移动
③五类:插入排序(直接插入排序;折半插入排序;希尔排序)、交换排序(冒泡排序、快速排序)、选择排序(简单选择排序;堆排序)、归并排序、基数排序

2.插入排序

为实现L[1…n]的排序,将L(2)~L(n)依次插入前面已排好序的子序列
①直接插入排序:每次从后往前寻找待插入的位置,时间复杂度O(n^2)
②折半插入排序:折半查找,减少元素比较次数但元素移动次数不变,因此时间复杂度仍为O(n^2)
希尔排序(缩小增量排序):把记录按下标的一定增量分组(一般初始是长度的一半,然后逐渐减半),对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。
希尔排序时间复杂度最坏仍为O(n^2),好时可达到O(n^1.3),但它不稳定,当相同关键字的记录被分到不同组时,其相对次序可能会改变
在这里插入图片描述

3.交换排序

①冒泡排序:O(n^2)(永远是相邻两位交换)
快速排序::对冒泡排序算法的改进(性能最优)
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。(分界值一般是左边第一个,将其取出另存)
(2)通过左右指针分别从两端向中间遍历,将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。(最后指针相遇的地方将分界值插入。)此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分数据长度均为1,排序完成。

4.选择排序

每次在后面选择最小的一个元素放在有序序列中他应该在的位置(方式是和那位的元素交换)(交换可以是不相邻的)
简单选择排序:第i轮,后续的n-i+1个记录中选取关键字最小的记录,与第i个数交换
简单选择排序和直接插入排序的区别:
两者都是第二for循环都是不断查找,简单选择排序是从i位置起不断往后找最小的,直接插入排序是从i位置起不断往前找合适的插入位置。
堆排序:堆是一个近似完全二叉树的结构,并满足:子结点的键值或索引总是小于(或者大于)它的父节点。
大顶堆:根结点最大;小顶堆:根结点最小 (堆只对父子结点的大小关系有要求,而对兄弟节点之间的大小关系没有要求。

堆排序:将n个元素建成初始堆,输出堆顶元素(最大值)后,将堆底元素送入堆顶,此时堆已被破坏,调整后,再输出堆顶元素。如此重复,即可输出递减序列。可见堆排序需要解决两个问题:
堆构造与调整:首先,对于一棵n个节点的完全二叉树,其最后一个结点编号是第(n/2)向下取整(从1开始数),
在这里插入图片描述
堆插入:将新节点放在堆末端,然后调整
如:
在这里插入图片描述

空间复杂度:O(1)
时间复杂度:O(nlog2n)

5.归并排序

n路归并:不断将前后n个相邻的有序表归并为一个有序表,直至成为一个有序表(双指针)【主要研究二路归并】
时间复杂度:每趟归并n,有log2n趟,共O(nlog2n)
空间复杂度:归并时需要O(n)
(与希尔排序分组的不同)
在这里插入图片描述

6.基数排序

只能对数字元素进行比较,元素最多有效位有几位就比较几趟
对于每位数字从后向前比较每一位
https://www.bilibili.com/video/BV1YM4y1A7wi?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=004a97c60ce7b19403906146d0b7240f

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值