生成森林:对非连通图,由各个连通分量的生成树的集合。
1.3.1、邻接矩阵(数组)表示法
建立一个顶点表(记录各个顶点信息)和一个邻接矩阵(表示各个顶点之间关系)
- 设图A=(V,E)有n个顶点,则
| i | 0 | 1 | 2 | … | n-1 |
| — | — | — | — | — | — |
| Vexs[i] | V1 | V2 | V3 | … | Vn |
- 图的邻接矩阵是一个二维数组A.arcs[n] [n],定义为:
A . a r c s [ i ] [ i ] = { 1 , 如 果 < i , j > ∈ E 或 者 ( i , j ) ∈ E 0 , 否 则 A.arcs[i][i]=\begin{cases} 1, 如果<i,j>∈E 或者(i,j)∈E\\ 0, 否则\end{cases} A.arcs[i][i]={1,如果<i,j>∈E或者(i,j)∈E0,否则
上述解释为:如果两个顶点之间存在边或者弧,那么二维数组就为1,如果两个顶点之间不存在边或者弧,那么二维数组就为0
1.3.1.1、无向图的邻接矩阵表示法
-
无向图的邻接矩阵是对称的。
-
顶点 i 的度 = 第i行(列)中 1 的个数。
-
特别的,完全图(任意两个顶点都有边)的邻接矩阵中,对角元素为0,其余均为1。
1.3.1.2、有向图的邻接矩阵表示法
在有向图的邻接矩阵中:
-
第i行含义:以结点Vi为尾的弧(即出度边)
-
第i列含义:以结点Vi为头的弧(即出度边)
分析:
-
有向图的邻接矩阵可能是不对称的。
-
顶点的出度 = 第 i 行元素之和
-
顶点的入度 = 第 i 列元素之和
-
顶点的度 = 第i行元素之和+第i列元素之和
1.3.1.3、网(有权图)的邻接矩阵表示法
A . a r c s [ i ] [ i ] = { W i j , < V i , V j > 或 ( V i , V j ) ∈ V R ∞ , 无 边 ( 弧 ) A.arcs[i][i]=\begin{cases} Wij, <Vi,Vj>或(Vi,Vj)∈VR\\ ∞, 无边(弧)\end{cases} A.arcs[i][i]={Wij,<Vi,Vj>或(Vi,Vj)∈VR∞,无边(弧)
1.3.2、邻接矩阵优缺点
邻接矩阵的优点:
-
直观、简单、好理解
-
方便检查任意一对顶点间是否存在边
-
方便找任一顶点的所有"邻接点"(有边直接相连的顶点)
-
方便计算任一顶点的"度"(从该点发出的边数为"出度",指向该点的边数为"入度")
-
无向图:对应行(或列)非0元素的个数
-
有向图:对应行非0元素的个数是"出度",对应列非0元素的个数是"入度"
缺点:
-
不便于删除和增加顶点
-
浪费空间-存稀疏图(点很多而边很少),有大量无效元素
-
对稠密图(特别是完全图)还是很合算的
-
浪费时间-统计稀疏图中一共有多少条边
1.3.3、邻接表(链式)表示法
1.3.3.1、无向图的邻接表
3表示V3,1表示V2。表示V1链接了V4,V1链接了V2
顶点:
- 按编号顺序将顶点数据存储在一维数组中。
关联同一顶点的边(以顶点为尾的弧):
- 用线性链表存储
无向图的邻接表特点:
-
邻接表不唯一
-
若无向图中有n个顶点、e条边,则其邻接表需n个头结点和2e个表结点。适宜存储稀疏图。
-
无向图中顶点Vi的度为第 i 个单链表中的结点数。
1.3.3.2、有向图的邻接表
只记录顶点发出的弧:邻接表
特点:找出度易,找入度难。
-
顶点Vi的出度为第i个单链表中的结点个数
-
顶点Vi的入度为整个单链表中邻接点域值是 i-1 的结点个数。
我们也可以只记录顶点进入的弧:逆邻接表
-
顶点Vi的入度为第i个单链表中的结点个数。
-
顶点Vi的出度为整个单链表中邻接点域值是 i-1 的结点个数
1.3.4、邻接表特点
-
方便找任一顶点的所有"邻接点"
-
节约稀疏图的空间
-
需要N个头指针+2E个结点(每个结点至少2个域)
-
方便计算任一顶点的"度"?
-
对无向图:是的
-
对有向图:只能计算"出度",需要构造"逆邻接表"(存指向自己的边)来方便计算入度
-
不方便检查任意一对顶点间是否存在边
1.3.5、邻接矩阵与邻接表的关系
联系:邻接表中每个链表对应于邻接矩阵中的一行,链表中结点个数等于一行中非零元素的个数。
区别:
-
对于任一确定的无向图,邻接矩阵是唯一的(行列号与顶点编号一致),但邻接表不唯一(链接次序与顶点编号无关)。
-
邻接矩阵的空间复杂度为O(n2),而邻接表的空间复杂度为O(n+e)
用途:邻接矩阵多用于稠密图,邻接表多用于稀疏图。
1.3.6、十字链表
十字链表是有向图的另一种链式存储结构。我们也可以把它看成是将有向图的邻接表和逆邻接表结合起来形成的一种链表。
有向图中的每一条弧对应十字链表中的一个弧结点,同时有向图中的每个顶点在十字链表中对应有一个结点,叫做顶点结点。
顶点结点:存储顶点数据、第一条出度边、第一条入度边
弧结点:
如上图,
第一条出度边,a->b(0->1), a-c(0->2)
第一条入度边,c->a(2->0), d->a(3->0)
1.3.7、邻接多重表
十字链表和邻接多重表初听挺难理解的,这里直接听视频讲解:https://www.bilibili.com/video/BV1nJ411V7bd?p=116
之后理解了再更新笔记记录!
从已给的连通图中某一顶点出发,沿着一些边访遍图中的所有的顶点,且使每个顶点仅被访问依次,就叫做图的遍历,它是图的基本运算。
图中可能存在回路,且图的任一顶点都可能与其他顶点相通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点。那么怎么样避免重复访问呢?
解决思路:设置辅助数组 visited[n],用来标记每个被访问过的顶点。
-
初始状态 visited[i] 为0
-
顶点i被访问,改visited[i]为1,防止被多次访问
1.4.1、深度优先搜索DFS
Depth_First Search DFS (一条道走到黑)
方法如下:
-
在访问图中某一起始顶点 v 后,由 v 出发,访问它的任一邻接顶点W1
-
再从 W1 出发,访问与 W1 邻接但还未被访问过的顶点W2
-
然后再从 W2 出发,进行类似的访问
-
如此进行下去,直至到达所有的邻接顶点都被访问过的顶点u为止
-
接着,退回一步,退到前一次刚访问过的顶点,看是否还有其他没有被访问的邻接顶点
-
如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问
-
如果没有,那就再退回一步进行搜索。重复上述过程,直到连通图中的所有顶点都被访问过为止。
连通图的深度优先遍历类似于树的先根遍历
1.4.2、广度优先搜索BFS
Breadth_First Search BFS
方法如下:
从图的某一顶点出发,首先依次访问该结点的所有邻接点Vi1,Vi2,Vi3…Vin ,再按这些顶点被访问的先后次序依次访问与它们想邻接的所有未被访问的顶点。重复此过程,直至所有顶点均被访问为止。
- 连通图的广度遍历
- 非连通图的广度遍历
1.5.1、最小生成树
生成树:所有顶点均由边链接在一起,但不存在回路的图。(将所有顶点都保持连通,边数最少,没有回路)
一个图可以有许多棵不同的生成树
所有生成树具有以下共同特点:
-
生成树的顶点个数与图的顶点个数相同
-
生成树是图的极小连通子图,去掉一条边则非连通
-
一个有n个顶点的连通图的生成树有 n-1 条边(含有n个顶点,n-1条边的图不一定是生成树。)
-
在生成树中再加一条边必然形成回路
-
生成树中任意两个顶点间的路径是唯一的。
1.5.1.1、无向图的生成树
顶点以及蓝色路径为生成树
设图 G=(V,E)是个连通图,当从图任一顶点出发遍历图G时,将边集E(G)分成两个集合T(G)和B(G)。其中T(G)是遍历图时所经过的边的集合,B(G)是遍历图时未经过的边的集合。显然,G1(V,T)是图G的极小连通子图。即子图G1是连通图G的生成树。
1.5.1.2、网的最小生成树
给定一个无向网,在该网中的所有生成树中,使得各边权值之和最小的那棵生成树称为该网的最小生成树,也叫最小代价生成树。
1.5.2、构造最小生成树
构造最小生成树的算法很多,其中多数算法都利用了 MST 的性质。
MST性质:设N=(V,E)是一个连通网,U是顶点集V的一个非空子集。若边(u,v)是一条具有最小权值的边,其中u∈U,v∈V-U,则必存在一棵包含边(u,v)的最小生成树。
1.5.2.1、Prim算法
算法思想:
-
设N=(V,E)是连通网,TE是N上最小生成树中边的集合
-
初始令 U={u0},(u0∈V),TE={}。
-
在所有 u ∈ U,v∈V-U的边(u,v)∈E中,找一条代价最小的边(u0,v0)
-
将(u0,v0)并入集合TE,同时v0并入U0
-
重复上述操作直至U=V为止,则T=(V,TE)为N的最小生成树。
例如:
我们要构造如下图的最小生成树,我们选取一个顶点,这个顶点就是U集合,其他顶点就是V-U集合
在U集合当中的顶点和V-U集合当中的顶点中找一条权值最小的边,将边关联的顶点选取到我们的U集合,其他顶点为V-U集合
之后在U集合当中的顶点和V-U集合当中的顶点中找一条权值最小的边,V1到V2为6,V1到V4为5,V3到V2为5,V3到V4为5,V3到V5为6,V3到V6为4。所以选取权值最小的边4,其关联的顶点为V6,将其加入到U集合中。此时U集合为{V1,V3,V6}
重复上述操作,V1周边的权值为6,5,V3周边的权值为5,5,6,V6周边的权值为6,V4周边不能选(一旦选了有回路成环了)
我们选择权值最小的V3到V2的5,将V2加入到U集合中
1.5.3.2、Kruskal算法
克鲁斯卡尔(Kruskal)算法
算法思想:
-
设连通网 N=(V,E),令最小生成树初始状态为只有 n 个顶点而无边的非连通图 T=(V,{}),每个顶点自成一个连通分量
-
在E中选取代价最小的边,若该边依附的顶点落在T中不同的连通分量上(即:不能形成环),则将此边加入到T中;否则,舍去此边,选取下一条代价最小的边。
-
以此类推,直到T中所有顶点都在同一连通分量上为止。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
总结
对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,
最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-OMeBZmDu-1712497093610)]
总结
对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,
[外链图片转存中…(img-CpGWnrVJ-1712497093610)]
[外链图片转存中…(img-Kkhtypnc-1712497093611)]
最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算