图的最小生成树(Prim算法、Kruskal算法)
目录
一、最小生成树
1.1 定义
1.2 性质
二、Prim算法
2.1 基本思想
2.2 算法思想
2.3 算法实现
三、Kruskal算法
3.1 基本思想
3.2 算法思想
3.3 算法实现
一、最小生成树
1.1 定义
1.2 性质
示意图:
二、Prim算法
2.1 基本思想
可以看出,Prim算法逐步向顶点集U中增加顶点, 故又称为“加点法”。
注意:选择最小边时,条件是边的一个顶点属于U,而另一个顶点属于V-U,即保证加点后不构成回路。在有多条同样权值的边可选时,可任选其一。
2.2 算法思想
说明:
下面给出一个实例。
CloseEdge[i].lowcost = 0 代表顶点 i 已被并入顶点集U中。
2.3 算法实现
定义数组CloseEdge[ ],用于记录从U到V-U的最小边。
typedef struct {int adjvex;int lowcost;
} CloseEdge[MAX_VERTEX_NUM];
Minium函数用于找出CloseEdge[ ]中最小的最小边。
int Minium(CloseEdge ce, int n) {int i, j = -1;int c = -1;for (i = 0; i < n; ++i) /* n是图G的顶点个数 */if (ce[i].lowcost != 0 && (c == -1 || c > ce[i].lowcost)) {c = ce[i].lowcost;/* j用于记录当前最小的最小边的顶点下标 */j = i; }return j;
}
Prim算法。
void MiniSpanTree_Prim(Graph *G, VertexData k) {int i, e;int u, v;CloseEdge ce;/* 确定起始顶点的下标 */u = LocateVertex(G, k);/* 初始化数组ce */ce[u].lowcost = 0;for (i = 0; i < G->vexnum; ++i)if (i != u) {ce[i].adjvex = u;ce[i].lowcost = G->arcs[u][i].adj;}/* 选出最小生成树的G->vexnum - 1条边 */for (e = 1; e <= G->vexnum - 1; ++e) {v = Minium(ce, G->vexnum);u = ce[v].adjvex;/* 打印得到的最小边 */printf("(%s, %s, %d)\n",Vertex2Name(G->vertex[u].data),Vertex2Name(G->vertex[v].data),ce[v].lowcost);/* 将顶点v纳入集合U */ce[v].lowcost = 0;for (i = 0; i < G->vexnum; ++i) /* 更新数组ce */if (G->arcs[v][i].adj < ce[i].lowcost) {ce[i].adjvex = v;ce[i].lowcost = G->arcs[v][i].adj;}}
}
三、Kruskal算法
3.1 基本思想
可以看出,Kruskal算法逐步增加生成树的边(注意加边后不能构成回路),与Prim算法相比,可称为“加边法”。
3.2 算法思想
下面给出一个实例。
初始化。
选出第一条边。
选出第二条边。
选出第三条边。
以此类推,直到所有的顶点都在一个顶点集合内。
3.3 算法实现
定义边的类型;数组VertexSet用于记录顶点存储状态。
typedef struct {int u, v;int lowcost;
} Edge;int VertexSet[MAX_VERTEX_NUM];
Minium函数用于找出图G中权值最小的边。
bool Minium(Graph *G, Edge *e) {int i, j;/* 清除使用痕迹 *//* 因为e是指针,所以其中的数据会被带出函数 */e->u = e->v = -1;e->lowcost = INFINITY;for (i = 0; i < G->vexnum; ++i)for (j = 0; j < G->vexnum; ++j)/* 要求顶点i和顶点j不能在同一个顶点集合内,否则会形成回路 */if (VertexSet[i] != VertexSet[j] && e->lowcost > G->arcs[i][j].adjvex) {e->lowcost = G->arcs[i][j].adjvex;e->u = i;e->v = j;}return e->u != -1;
}
Kruskal算法。
void MiniSpanTree_Kruskal(Graph *gn) {Edge e;int i, setid;int u, v;/* 初始化数组VertexSet */for (i = 0; i < gn->vexnum; ++i)VertexSet[i] = i;/* 最大的集合编号 */setid = i;while (Minium(gn, &e)) {/* 打印得到的最小边 */printf("(%s, %s, %d)\n",Vertex2Name(gn->vertex[e.u].data),Vertex2Name(gn->vertex[e.v].data),e.lowcost);u = VertexSet[e.u];v = VertexSet[e.v];/* 更新顶点集合状态 */for (i = 0; i < gn->vexnum; ++i)if (u == VertexSet[i] || v == VertexSet[i])VertexSet[i] = setid;++setid;}
}
说明:
1、每合并得到一个新的顶点集合,其编号都设为当前setid的值。
2、if (u == VertexSet[i] || v == VertexSet[i]) 不仅更新顶点 u 和 v 的集合编号,同时也会更新与顶点 u 或 v 同属一个集合的顶点的集合编号。
图的最小生成树(Prim算法、Kruskal算法)相关推荐
- 数据结构(六):图的概念、存储方式、基本操作、最小生成树、最短路径、有向无环图、关键路径 | Prim、Kruskal算法 | BFS、Dijkstra、Floyd算法 | 拓扑排序 | 求关键路径
文章目录 第六章 图 一.图 (一)图的定义 (二)图逻辑结构的应用 (三)无向图.有向图 (四)简单图.多重图 (五)顶点的度.入度.出度 (六)顶点-顶点的关系描述 (七)连通图.强连通图 (八) ...
- 最小生成树(Prim、Kruskal)算法,秒懂!
前言 在数据结构与算法的图论中,(生成)最小生成树算法是一种常用并且和生活贴切比较近的一种算法.但是可能很多人对概念不是很清楚,什么是最小生成树? 一个有 n 个结点的连通图的生成树是原图的极小连通子 ...
- dijkstra算法_Python实现图的经典DFS、BFS、Dijkstra、Floyd、Prim、Kruskal算法
讲在前面的话,图的算法太多,理论知识肯定一篇文章讲不完,关于理论知识大家可以参考教材Sedgewick的<算法>或reference的链接,本文主要还是想在一篇文章中记录六种算法的Pyth ...
- dfs时间复杂度_Python实现图的经典DFS、BFS、Dijkstra、Floyd、Prim、Kruskal算法
讲在前面的话,图的算法太多,理论知识肯定一篇文章讲不完,关于理论知识大家可以参考教材Sedgewick的<算法>或reference的链接,本文主要还是想在一篇文章中记录六种算法的Pyth ...
- 生成树的概念,最小生成树Prim算法 Kruskal算法
求解最小生成树可以用Prim算法 Kruskal算法
- 最小生成树原理及Kruskal算法的js实现
1. 生成树和最小生成树的概念 设图G(V,E)连通,则 生成树:包含图G(V,E)中的所有节点,及|V|-1条边的连通图,一个图的生成树可以有多颗 最小生成树:最小权重生成树,在生成树的概念上加一个 ...
- Prim和Kruskal算法应用----城市水管连接
Prim和Kruskal算法应用----城市水管连接 问题描述: Description: 现在有n个城镇,编号为1, 2, 3, 4-n.他们之间有m条互通的道路,每条道路有相应的长度,现在基于这些 ...
- 【图解】Prim和Kruskal算法的区别
[贪心]Prim和Kruskal算法的区别 Kruskal算法和Prim算法的优劣 Kruskal算法,相较于Prim算法是基于点的操作,Kruskal算法是基于边的操作,思想也比Prim简单,更容易 ...
- 可视化最小生成树Prim、Kruskal
代码下载链接:(41条消息) 可视化最小生成树Kruskal,DEV配EGE-C文档类资源-CSDN文库 代码下载链接:(41条消息) 可视化最小生成树Prim,DEV配EGE-C文档类资源-CSDN ...
- 基本数据结构(图: 基本结构,DFS,prim算法, kruskal算法)
#include <iostream> using namespace std; //约定: //1. 图是由很多节点(VERTEX)构成的, 因此图结构是由一个VERTEX的链表构成的, ...
最新文章
- Gut:人体最初的微生物起源与生殖健康
- 【机器学习】如何通俗易懂地阐述机器学习?
- OpenCV计算图像的平均值和标准差的函数meanStdDev函数的使用
- 云计算比本地计算机可靠,1-云计算复习题
- Spring(七)持久层
- Hybris commerce的promotion rule里的固定折扣功能
- 【c语言】 gets()函数不执行/被跳过
- 【高并发解决方案】1、高并发解决方案汇总
- python练习题及答案-python编程练习题和答案.doc
- CS代理+proxychains+nmap进行内网扫描
- 科大讯飞麦克风阵列AIUI开放平台基本操作初级
- 【最新】iOS App上架AppStore 教程 (Part 二)
- Java - 对象克隆
- mysql Miscellaneous notes
- 用xinnet新网API实现动态域名
- alertmanager设置告警邮件的邮件头/邮件模板
- 实体店商家微信会员系统开发步骤_分享微信会员系统优势
- 引入PageHelper.startPage(pageNum,pageSize);后报错
- akka java ask_Akka Stream之集成
- 数据结构实验_大学数据统计