IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 最小生成树:Kruskal算法 -> 正文阅读

[数据结构与算法]最小生成树:Kruskal算法

最小生成树:Kruskal算法

Kruskal算法的思想就是站在上帝视角,把整个图中权值最短的边一个个挑出来.

顶点数组

辅助数组(此数组旨在避免在构造最小生成树时产生回路)
V e x s e t [ i ] Vexset[i] Vexset[i] :标识各个顶点所属的连通分量.表示该顶点所在的连通分量
V e x s e t [ i ] = i Vexset[i]=i Vexset[i]=i :开始时每个顶点都自成一个连通分量
辅助数组的初始值:
V e x s e t [ i ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 } Vexset[i]=\{0,1,2,3,4,5,6,7,8\} Vexset[i]={0,1,2,3,4,5,6,7,8}

边集数组
E d g e [ i ] Edge[i] Edge[i]:存储边的顶点下标和权值

typedef struct{
	VerTexType begin;	//边的始点下标
	VerTexType end;		//边的终点下标
	ArcType weight;		//边的权值
}Edge[arcnum];

将邻接矩阵通过程序转化为边集数组,并按权值从小到大排序


找出整个图中权值最小的边 ( V 4 , V 7 ) (V_4,V_7) (V4?,V7?)

至此连通分量有:
V 4 V_4 V4? , V 7 V_7 V7? 构成的一个连通分量
其余每个顶点都依旧各自自成一个连通分量

找出目前权值最小的边 ( V 2 , V 8 ) (V_2,V_8) (V2?,V8?)

至此连通分量有:
V 2 V_2 V2? , V 8 V_8 V8? 构成的一个连通分量
V 4 V_4 V4? , V 7 V_7 V7? 构成的一个连通分量
其余每个顶点都依旧各自自成一个连通分量

找出目前权值最小的边 ( V 0 , V 1 ) (V_0,V_1) (V0?,V1?)

至此连通分量有:
V 0 V_0 V0? , V 1 V_1 V1? 构成的一个连通分量
V 2 V_2 V2? , V 8 V_8 V8? 构成的一个连通分量
V 4 V_4 V4? , V 7 V_7 V7? 构成的一个连通分量
其余每个顶点都依旧各自自成一个连通分量

找出目前权值最小的边 ( V 0 , V 5 ) (V_0,V_5) (V0?,V5?)

V 0 V_0 V0? , V 1 V_1 V1? 构成一个连通分量
V 0 V_0 V0? , V 5 V_5 V5? 构成一个连通分量
因为边 ( V 0 , V 1 ) (V_0,V_1) (V0?,V1?) 和 边 ( V 0 , V 5 ) (V_0,V_5) (V0?,V5?) 中都有 V 0 V_0 V0? 所以两个连通分量: 边 ( V 0 , V 1 ) (V_0,V_1) (V0?,V1?) 和 边 ( V 0 , V 5 ) (V_0,V_5) (V0?,V5?)合并为一个连通分量

至此连通分量有:
V 0 V_0 V0? V 1 V_1 V1? V 5 V_5 V5? 构成的一个连通分量
V 2 V_2 V2? , V 8 V_8 V8? 构成的一个连通分量
V 4 V_4 V4? , V 7 V_7 V7? 构成的一个连通分量
其余每个顶点都依旧各自自成一个连通分量

找出目前权值最小的边 ( V 1 , V 8 ) (V_1,V_8) (V1?,V8?)

V 0 V_0 V0?, V 1 V_1 V1?, V 5 V_5 V5? 构成一个连通分量
V 1 V_1 V1? , V 8 V_8 V8? 构成一个连通分量
V 2 V_2 V2? , V 8 V_8 V8? 构成一个连通分量

因为连通分量 V 0 , V 1 , V 5 V_0,V_1,V_5 V0?,V1?,V5? 和连通分量 V 1 , V 8 V_1,V_8 V1?,V8? 之间都有 V 1 V_1 V1?
因为连通分量 V 1 , V 8 V_1,V_8 V1?,V8? 和连通分量 V 2 , V 8 V_2,V_8 V2?,V8? 之间都有 V 8 V_8 V8?
以上所有连通分量合并为一个连通分量 V 0 , V 1 , V 5 , V 8 , V 2 V_0,V_1,V_5,V_8,V_2 V0?,V1?,V5?,V8?,V2?

至此连通分量有:
V 0 , V 1 , V 5 , V 8 , V 2 V_0,V_1,V_5,V_8,V_2 V0?,V1?,V5?,V8?,V2? 构成的一个连通分量
V 4 V_4 V4? , V 7 V_7 V7? 构成的一个连通分量
其余每个顶点都依旧各自自成一个连通分量

找出目前权值最小的边 ( V 3 , V 7 ) (V_3,V_7) (V3?,V7?)

V 4 V_4 V4? , V 7 V_7 V7? 构成一个连通分量
V 3 V_3 V3? , V 7 V_7 V7? 构成一个连通分量
上述两个连通分量中都有 V 7 V_7 V7? 所以将这两个连通分量合并为一个连通分量 V 3 , V 4 , V 7 V_3,V_4,V_7 V3?,V4?,V7?

至此连通分量有:
V 0 , V 1 , V 5 , V 8 , V 2 V_0,V_1,V_5,V_8,V_2 V0?,V1?,V5?,V8?,V2? 构成的一个连通分量
V 3 V_3 V3?, V 4 V_4 V4?, V 7 V_7 V7? 构成的一个连通分量
其余每个顶点都依旧各自自成一个连通分量

找出目前权值最小的边 ( V 1 , V 6 ) (V_1,V_6) (V1?,V6?)
V 0 , V 1 , V 5 , V 8 , V 2 V_0,V_1,V_5,V_8,V_2 V0?,V1?,V5?,V8?,V2? 构成一个连通分量
V 1 , V 6 V_1,V_6 V1?,V6? 构成一个连通分量
以上两个连通分量中都有 V 1 V_1 V1? 所以这两个连通分量合并成一个连通分量 V 0 , V 1 , V 5 , V 8 , V 2 , V 6 V_0,V_1,V_5,V_8,V_2,V_6 V0?,V1?,V5?,V8?,V2?,V6?

至此连通分量有:
V 0 , V 1 , V 5 , V 8 , V 2 , V 6 V_0,V_1,V_5,V_8,V_2,V_6 V0?,V1?,V5?,V8?,V2?,V6? 构成的一个连通分量
V 3 V_3 V3?, V 4 V_4 V4?, V 7 V_7 V7? 构成的一个连通分量

找出目前权值最小的边 ( V 6 , V 7 ) (V_6,V_7) (V6?,V7?)

V 6 , V 7 V_6,V_7 V6?,V7? 构成一个连通分量
V 0 , V 1 , V 5 , V 8 , V 2 , V 6 V_0,V_1,V_5,V_8,V_2,V_6 V0?,V1?,V5?,V8?,V2?,V6? 构成一个连通分量
V 3 V_3 V3?, V 4 V_4 V4?, V 7 V_7 V7? 构成一个连通分量
以上三个连通分量由于 V 6 , V 7 V_6,V_7 V6?,V7? 而合并成一个连通分量 V 0 , V 1 , V 5 , V 8 , V 2 , V 6 , V 7 , V 3 , V 4 V_0,V_1,V_5,V_8,V_2,V_6,V_7,V_3,V_4 V0?,V1?,V5?,V8?,V2?,V6?,V7?,V3?,V4?

至此连通分量有:
V 0 , V 1 , V 5 , V 8 , V 2 , V 6 , V 7 , V 3 , V 4 V_0,V_1,V_5,V_8,V_2,V_6,V_7,V_3,V_4 V0?,V1?,V5?,V8?,V2?,V6?,V7?,V3?,V4?

至此最小生成树构造完成

《数据结构C语言版》内的Kruskal算法描述

void MiniSpanTree_Kruskal(AMGraph G){
	Sort(Edge);	//按边的权值将边集数组元素从小到大排序
	for(i=0; i<G.vexnum; ++i)	//初始化辅助数组,各个顶点自成连通分量
		Vexset[i]=i;
	for(i=0; i<G.arcnum; ++i){
		v1=LocateVex(G,Edge[i].begin);	//边集数组中第i个元素中边的始点
		v2=LocateVex(G,Edge[i].end);	//边集数组中第i个元素中边的终点
		vs1=Vexset[v1];	//获取边Edge[i]的始点所在的连通分量
		vs2=Vexset[v2];	//获取边Edge[i]的终点所在的连通分量
		if(vs1 != vs2){	//边的两个顶点分属于不同的连通分量
			cout << Edge[i].begin << Edge[i].end;	//输出此边
			for(j=0; j<G.vexnum; ++j)	//合并vs1和vs2两个连通分量,即两个集合统一编号
				if(Vexset[j] == vs2)	//集合编号为vs2的都改为vs1
					Vexset[j]=vs1;		
		}
	}
}

《大话数据结构》内的Kruskal算法描述

void MiniSpanTree_Kruskal(MGraph){
	int i,n,m;
	Edge edges[MAXEDGE]; //定义边集数组
	int parent[MAXVEX];	 //定义数组parent来判断边与边是否形成环路(实质为并查集)
	Sort(edges);	//把边集数组中的边按权值从小到大排序
	for(i=0; i<G.numVertiexes; i++)	//初始化数组parent
		parent[i]=0;
	for(i=0; i<G.numEdges; i++){	//循环每一条边
		n = Find(parent,edges[i].begin); //边的始点下标
		m = Find(parent,edges[i].end);	//边的终点下标
		if(n != m){		//假如n不等于m,说明此边没有与现有的生成树形成环路
			parent[n]=m; //将此边的的终点放入parent中(此数组下标代表始点)表示此顶点已经在生成树集合中
			printf("(%d,%d) %d\n", edges[i].begin,edges[i].end,edges[i].weight);
		}
	}
}
//查找边的终点下标
int Find(int *parent, int f){
	while(parent[f] > 0){
		f = parent[f];
	}
	return f;
}


  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-18 12:56:50  更:2021-08-18 12:57:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 16:51:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计