从零开始学数据结构系列之第四章《克鲁斯卡尔算法步骤回顾》


详情1

例如,下面是一个无向带权连通图,采用克鲁斯卡尔算法生成最小生成树:

在这里插入图片描述
1、将图中所有边对应的权值,按从小到大排序如下:1,2,3,4,5,6,8。
2、可知权值1最小,首先连接V4和V6:
3、选择权值2,连接V6与V5:
在这里插入图片描述
3、选择权值3,选取V4与V1连接:

在这里插入图片描述
4、选择权值4,连接V1与V3:
在这里插入图片描述
5、选取权值5,连接V4与V2,最终得到最小生成树如下(该最小生成树的代价为4+3+1+5+2=15):
在这里插入图片描述

详情2

  Kruskal(克鲁斯卡尔)算法开始时,认为每一个点都是孤立的,分属于n个独立的集合。

在这里插入图片描述
5个集合{ {1},{2},{3},{4},{5} }

生成树中没有边
   Kruskal每次都选择一条最小的边,而且这条边的两个顶点分属于两个不同的集合。将选取的这条边加入最小生成树,并且合并集合。
第一次选择的是<1,2>这条边,将这条边加入到生成树中,并且将它的两个顶点1、2合并成一个集合。
在这里插入图片描述
4个集合{ {1,2},{3},{4},{5} }
生成树中有一条边{ <1,2> }
  第二次选择的是<4,5>这条边,将这条边加入到生成树中,并且将它的两个顶点4、5合并成一个集合。

在这里插入图片描述

3个集合{ {1,2},{3},{4,5} }
生成树中有2条边{ <1,2> ,<4,5>}
  第三次选择的是<3,5>这条边,将这条边加入到生成树中,并且将它的两个顶点3、5所在的两个集合合并成一个集合
在这里插入图片描述
2个集合{ {1,2},{3,4,5} }
生成树中有3条边{ <1,2> ,<4,5>,< 3,5>}
  第四次选择的是<2,5>这条边,将这条边加入到生成树中,并且将它的两个顶点2、5所在的两个集合合并成一个集合。

在这里插入图片描述
1个集合{ {1,2,3,4,5} }
生成树中有4条边{ <1,2> ,<4,5>,< 3,5>,<2,5>}
算法结束,最小生成树权值为19。

​   通过上面的模拟能够看到,Kruskal算法每次都选择一条最小的,且能合并两个不同集合的边,一张n个点的图总共选取n-1次边。因为每次我们选的都是最小的边,所以最后的生成树一定是最小生成树。每次我们选的边都能够合并两个集合,最后n个点一定会合并成一个集合。通过这样的贪心策略,Kruskal算法就能得到一棵有n-1条边,连接着n个点的最小生成树。

应用场景-公交站问题

在这里插入图片描述

  1. 某城市新增 7 个站点(A, B, C, D, E, F, G) ,现在需要修路把 7 个站点连通
  2. 各个站点的距离用边线表示(权) ,比如 A – B 距离 12 公里
  3. 问:如何修路保证各个站点都能连通,并且总的修建公路总里程最短?

以上图为例,来对克鲁斯卡尔进行演示(假设用数组 R 保存最小生成树结果)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第1步:将边<E,F>加入 R 中。

​   边<E,F>的权值最小,因此将它加入到最小生成树结果 R 中。

第2步:将边<C,D>加入 R 中。

​   上一步操作之后,边<C,D>的权值最小,因此将它加入到最小生成树结果 R 中。

第3步:将边<D,E>加入 R 中。

​   上一步操作之后,边<D,E>的权值最小,因此将它加入到最小生成树结果 R 中。

第4步:将边<B,F>加入 R 中。

​   上一步操作之后,边<C,E>的权值最小,但<C,E>会和已有的边构成回路;因此,跳过边<C,E>。同理,跳过边<C,F>。将边<B,F>加入到最小生成树结果 R 中。

第5步:将边<E,G>加入 R 中。

​   上一步操作之后,边<E,G>的权值最小,因此将它加入到最小生成树结果 R 中。

第6步:将边<A,B>加入 R 中。
  上一步操作之后,边<F,G>的权值最小,但<F,G>会和已有的边构成回路;因此,跳过边<F,G>。同理,跳过边<B,C>。将边<A,B>加入到最小生成树结果 R 中。

​   此时,最小生成树构造完成!它包括的边依次是:<E,F> <C,D> <D,E> <B,F> <E,G> <A,B>

回路讲解

在这里插入图片描述
  在将<E,F> <C,D> <D,E>加入到最小生成树 R 中之后,这几条边的顶点就都有了终点:

  • C 的终点是 F。
  • D 的终点是 F。
  • E 的终点是 F。
  • F 的终点是 F。

关于终点的说明:

​   就是将所有顶点按照从小到大的顺序排列好之后;某个顶点的终点就是"与它连通的最大顶点"。

​   因此,接下来,虽然<C,E>是权值最小的边。但是 C 和 E 的终点都是 F,即它们的终点相同,因此,将<C,E>加入最小生成树的话,会形成回路。这就是判断回路的方式。也就是说,我们加入的边的两个顶点不都指向同一个终点,否则将构成回路

通俗来讲我们可以用下面的图来进行表示
在这里插入图片描述
他的权值可以表示为{1,2,3,4,5,5,5,6,6,6}共10条

  我们每个节点可以设置他的起点和重点,初始化的时候,他的起点以及终点都是他自己本身

如下图初始化时:

节点起点终点
111
222
333
444
555
666

我们根据上述的权值进行连线{1,2,3,4,5,5,5,6,6,6}
在这里插入图片描述
此时他的黑色代表为他的终点值
在这里插入图片描述
第一次连接后,3这个节点的终点值 变为 1
在这里插入图片描述
第二次连接后,6这个节点的终点值 变为 4

在这里插入图片描述
第三次连接后,5这个节点的终点值 变为 2
在这里插入图片描述
第四次连接后,3,1这个节点的终点值 变为 4
在这里插入图片描述
   第五次连接时,如果将3,4这个节点连接的话,则回发现他的起始值和终点值相同,则构成回路,所以不进行链接,所以直接跳过这个继续进行连接
在这里插入图片描述
  类似于上面说的,总的来说就是借助一个数组来进行判断就行了,如果他的值相同则证明他时回路,否则可以进行连接

往期回顾

1.【第一章】《线性表与顺序表》
2.【第一章】《单链表》
3.【第一章】《单链表的介绍》
4.【第一章】《单链表的基本操作》
5.【第一章】《单链表循环》
6.【第一章】《双链表》
7.【第一章】《双链表循环》
8.【第二章】《栈》
9.【第二章】《队》
10.【第二章】《字符串暴力匹配》
11.【第二章】《字符串kmp匹配》
12.【第三章】《树的基础概念》
13.【第三章】《二叉树的存储结构》
14.【第三章】《二叉树链式结构及实现1》
15.【第三章】《二叉树链式结构及实现2》
16.【第三章】《二叉树链式结构及实现3》
17.【第三章】《二叉树链式结构及实现4》
18.【第三章】《二叉树链式结构及实现5》
19.【第三章】《中序线索二叉树理论部分》
20.【第三章】《中序线索二叉树代码初始化及创树》
21.【第三章】《中序线索二叉树线索化及总代码》
22【第三章】《先序线索二叉树理论及线索化》
23【第三章】《先序线索二叉树查找及总代码》
24【第三章】《后续线索二叉树线索化理论》
25【第三章】《后续线索二叉树总代码部分》
26【第三章】《二叉排序树基础了解》
27【第三章】《二叉排序树代码部分》
28【第三章】《二叉排序树代码部分》
29【第三章】《平衡二叉树基础概念》
30【第三章】《平衡二叉树的平衡因子》
31【第三章】《平衡二叉树的旋转基础详解》
32【第三章】《平衡二叉树的旋转类型图文详解》
33【第三章】《平衡二叉树的旋转类型总结及总代码》
34【第三章】《哈夫曼树简单了解》
35【第三章】《哈夫曼树的构造方法》
36【第三章】《哈夫曼编码构造及代码》
37【第四章】《图的定义》
38【第四章】《图的基本概念和术语》
39【第四章】《图的存储结构》
40【第四章】《图的遍历之深度优先遍历》
41【第四章】《广度优先遍历BFS》
42【第四章】《图的遍历总代码》
43【第四章】《最小生成树概念》
44【第四章】《最小生成树的应用举例》
45【第四章】《prim算法(普里姆算法)详解》
46【第四章】《prim算法(普里姆算法)详解2》
47【第四章】《prim算法(普里姆算法)详解3》
48【第四章】《prim算法(普里姆算法)讲解汇总》
49【第四章】《prim算法(普里姆算法)代码讲解》
50【第四章】《prim算法(普里姆算法)总代码》
51【第四章】《克鲁斯卡尔算法思路介绍》
52【第四章】《克鲁斯卡尔算法步骤思路1》
53【第四章】《克鲁斯卡尔算法步骤思路2》
54【第四章】《克鲁斯卡尔算法应用场景-公交站问题》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值