目录

一、克鲁斯卡尔(Kruskal)算法

二、普里姆(Prim)算法

三、两个算法对比


求图的最小生成树的典型算法:

  1. 克鲁斯卡尔(Kruskal)算法

  2. 普里姆(Prim)算法

注:考虑问题的出发点相同:为使生成树上边的权值之和达到最小,则应使生成树中每一条边的权值尽可能的小。

一、克鲁斯卡尔(Kruskal)算法

1)概述

  • 先构造一个只含n个顶点的子图SG,然后从权值最小的边开始,若它的添加不使SG中产生回路【不产生回路】,则在SG上加上这条边,如此重复,直至加上n-1条边为止。

2)算法分析

  • 设图G=(V, E) 是一个具有n个顶点的连通无向图,T=(V, TE)是图G的最小生成树。

    • V是T的顶点集

    • TE是T的边集

  • 构建最小生成树的步骤:

    1. T的初始化状态 T = (V, 空 ) ,即最小生成树T是图G的生成零图。

    2. 将图G中的边按照权值从小到大的顺序排序

    3. 依次选取每条边,若选取的边未使生成树T形成回路,则加入TE中,否则舍弃。直至TE中包含n-1条边为止

 例:

3)性能分析

  • 构建最小生成树时,尽可能选择权值最小的边,但并不是每一条权值最小的边都必然可选,有可能构成回路。

  • 最小生成树不是唯一的,因为同一时候可能有多重选择。

  • 算法的时间复杂度:O(elge) ,即克鲁斯卡尔算法的执行时间主要取决于图的边数

  • 该算法适用于针对==稀疏图==的操作。


二、普里姆(Prim)算法

1)概述

  • 取图中任意一个顶点v作为生成树的根,之后往生成树上添加新的顶点w

  • 在添加顶点w和已经在生成树上的顶点v之间必定存在一条边,并且该边的权值在所有连通顶点v和w之间的边中取值最小

  • 之后继续往生成树上添加顶点,直至生成树上含有n-1个顶点为止。

2)算法分析

例:从a顶点出发

补充概念:

  • 两个顶点之间的距离:指将顶点邻接到的关联边的权值

    记为:|u,v|

  • 顶点到顶点集合之间的距离:指顶点到顶点集合中所有顶点之间的距离中的最小值。

    记为:|u, V| = min |u,v|

  • 两个顶点集合之间的距离:指顶点集合到顶点集合中所有顶点之间的距离中的最小值。

    记为:|U, V| = min |u, V|

3)步骤分析

在生成树的构造过程中,图中n个顶点分属两个集合已落在生成树上的顶点集合U尚未落在生成树上的顶级集合V-U,则应在所有连通U中顶点和V-U中的顶点的边中选取权值最小的边

4)代码实现

程序最后运行结果:

 辅助数组:

 算法:

public class MiniSpanTree_PRIM {// 内部类辅助记录从顶点U到V-U的代价最小的边private class CloseEdge {Object adjVex;int lowCost;public CloseEdge(Object adjVex, int lowCost) {this.adjVex = adjVex;     //顶点this.lowCost = lowCost;        //两个顶点之间最下的权值,}}// 用普里姆算法从第u个顶点出发构造网G的最小生成树T,返回由生成树边组成的二维数组public Object[][] PRIM(MGraph G, Object u) throws Exception {// 用于记录最小生成树的顶点,例如:tree[0][0]="v0",tree[0][1]="v2"Object[][] tree = new Object[G.getVexNum() - 1][2];int count = 0; // 初始化数据CloseEdge[] closeEdge = new CloseEdge[G.getVexNum()];int k = G.locateVex(u);                      //当前节点在for (int j = 0; j < G.getVexNum(); j++)        // 辅助数组初始化if (j != k)closeEdge[j] = new CloseEdge(u, G.getArcs()[k][j]);// 当最小权值为0时,表示当前节点已经在树中closeEdge[k] = new CloseEdge(u, 0);            // 初始,U={u}for (int i = 1; i < G.getVexNum(); i++) {  // 选择其余G.vexnum - 1个顶点k = getMinMum(closeEdge);                // 求出T的下一个结点:第k个顶点tree[count][0] = closeEdge[k].adjVex; // 生成树的边放入数组tree[count][1] = G.getVexs()[k];       //count++;closeEdge[k].lowCost = 0;              // 第k个顶点并入U集for (int j = 0; j < G.getVexNum(); j++)   //新顶点并入U后重新选择最小边if (G.getArcs()[k][j] < closeEdge[j].lowCost)closeEdge[j] = new CloseEdge(G.getVex(k), G.getArcs()[k][j]);}return tree;}//在closeEdge中选出lowCost最小且不为0的顶点private int getMinMum(CloseEdge[] closeEdge) {int min = Integer.MAX_VALUE;int v = -1;for (int i = 0; i < closeEdge.length; i++)if (closeEdge[i].lowCost != 0 && closeEdge[i].lowCost < min){min = closeEdge[i].lowCost;v = i;}return v;}
}

测试类:

public class Example6_4 {public final static int INFINITY = Integer.MAX_VALUE;public static void main(String[] args) throws Exception {Object vexs[] = { "v0", "v1", "v2", "v3", "v4", "v5" };// 各顶点之间边的关系int[][] arcs = { { 0, 7, 1, 5, INFINITY, INFINITY },{ 7, 0, 6, INFINITY, 3, INFINITY }, { 1, 6, 0, 7, 6, 4 },{ 5, INFINITY, 7, 0, INFINITY, 2 },{ INFINITY, 3, 6, INFINITY, 0, 7 },{ INFINITY, INFINITY, 4, 2, 7, 0 } };MGraph G = new MGraph(GraphKind.UDG, 6, 10, vexs, arcs);Object[][] T = new MiniSpanTree_PRIM().PRIM(G, "v1");for (int i = 0; i < T.length; i++)System.out.println(T[i][0] + " - " + T[i][1]);}
}
// 开始顶点v1 调试结果:
// v1 - v4
// v1 - v2
// v2 - v0
// v2 - v5
// v5 - v3// 开始顶点v0 调试结果:
//v0 - v2
//v2 - v5
//v5 - v3
//v2 - v1
//v1 - v4

5)性能分析

  • 普利姆算法的时间复杂度为:O(n2),执行时间主要取决于图的顶点数,与边数无关。

  • 该算法适用于==稠密图==的操作。


三、两个算法对比

普里姆算法 克鲁斯卡尔算法
时间复杂度 O(n2) O(eloge)
适应范围 稠密图 稀疏图
执行时间 取决于图的顶点数 取决于图的边数
执行步骤 任意一顶点V作树的根,之后往树上添加边中权值最小的顶点W,不产生回路 构造一个顶点,从权值最小的边开始,不产生回路

写到最后

四季轮换,已经数不清凋零了多少, 愿我们往后能向心而行,一路招摇胜!

【数据结构】克鲁斯卡尔(Kruskal)算法 —PK— 普里姆(Prim)算法相关推荐

  1. 普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法

    图是一种基础又重要的数据结构,图的生成树是图的一个极小连通子图.最小生成树是无向连通网的所有生成树中边的权值之和最小的一棵生成树.求图的最小生成树可以牵引出很多经典的题目,例如在N个城市之间建立通讯网 ...

  2. 数据结构与算法(7-3)最小生成树(普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法)

    目录 一.最小生成树简介 二.普里姆算法(Prim) 1.原理 2.存储 2-1.图顶点和权: 2-3. 最小生成树: 3.Prim()函数 3-1.新顶点入树 3-2.保留最小权 3-3. 找到最小 ...

  3. 最小生成树——普里姆(Prim)算法

    Prim算法的基本思想是以顶点为主导地位:从起始顶点出发,通过选择当前可用的最小权值的边把其他顶点加入到生成树中来.设连通无向网为G(V,E),在普里姆算法中,将顶点集合V分成两个子集T和T'. (1 ...

  4. 一文带你弄懂普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法

    Prim算法 Prim算法用于构造最小生成树,且适用于稠密图. 基本思想 : 归并顶点 设连通网络 N = { V, E } 从某顶点 u0 出发, 选择与它关联的具有最小权值的边(u0, v), 将 ...

  5. 数据结构与算法|最小生成树算法(普里姆算法、克鲁斯卡尔算法)

    最小生成树算法 C语言代码部分来自小甲鱼的<数据结构与算法> 文章目录 最小生成树算法 一.普里姆(Prim)算法 1.C语言代码 2.算法思路 二.克鲁斯卡尔(Kruskal)算法 1. ...

  6. 十大算法之普里姆算法

    普里姆算法介绍 普利姆(Prim)算法求最小生成树,也就是在包含n个顶点的连通图中,找出只有(n-1)条边包含所有n个顶点的连通子图,也就是所谓的极小连通子图 普利姆的算法如下: 设G=(V,E)是连 ...

  7. 【数据结构与算法】普里姆算法的介绍和修路问题程序实现

    目录 1. 最小生成树的介绍 2. 普里姆算法的介绍 3. 修路问题的介绍 1. 最小生成树的介绍 最小生成树(Minimum Cost Spanning Tree),简称MST.给定一个带权的无向连 ...

  8. 我所知道的十大常用算法之普里姆算法(最小生成树)

    前言需求 今天我们学习的是普里姆算法,我们还是从一个场景里引入看看 有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通 1.各个村庄的距离用边线表示(权) ,比如 A ...

  9. prim算法(普里姆算法)详解

    prim算法(普里姆算法)详解 了解了什么是最小生成树后,本节为您讲解如何用普里姆(prim)算法查找连通网(带权的连通图)中的最小生成树. 普里姆算法查找最小生成树的过程,采用了贪心算法的思想.对于 ...

最新文章

  1. 用window.open时能否通过post方式传输数据?
  2. 嵌入式开发都需要会些什么
  3. 使用 Stream API 高逼格 优化 Java 代码!
  4. 官网mysql安装目录_官网下载MySQL 并安装
  5. 热传导/物质扩散算法应用于推荐
  6. java基础:13.2 集合框架 - LinkedList、Queue
  7. windows 任务管理中各个内存项的含义
  8. emos mysql_企业邮件部署详细步骤(EMOS)
  9. php excel复选框,excel如何实现下拉框复选
  10. composer报错解决
  11. 程序集定义(Assembly Definition File)
  12. Tga图片格式分析以及程序实现
  13. python画成绩正态分布图_正态分布为何如此重要?
  14. 阿里云服务器配置外网访问
  15. 实际采用 FleaPHP 的网站
  16. 太太丘舍去_太丘舍去,去后乃至(离开)——青夏教育精英家教网——
  17. 小米android11适配计划,小米已推出安卓11的MIUI12稳定版,这32款手机在适配行列...
  18. java入门123pdf二维码pdf_Java入门123:一个老鸟的Java学习心得 pdf
  19. Linux常用工具大全
  20. 树莓派+USB摄像头进行网络监控—MJPG-Streamer

热门文章

  1. 考个研究生,还能列入失信人员名单?那有没有失信导师名单,失信学校名单?...
  2. 【BZOJ1192】鬼谷子的钱袋——二分思想
  3. 怎么让网页变成黑白色?
  4. 蓝桥杯 调手表 BFS
  5. 计算机有符号数为什么采用补码表示
  6. 在谷歌控制台上怎么换行_如何在Google表格中的单元格中换行
  7. 起点中文网(主要是在目录下创建文件)
  8. 网易java版存档在哪儿_网易我的世界怎么导入存档 网易中国版手游存档位置
  9. 人脸变妆-人脸美颜-人脸美型-人脸替换-人脸滤镜-人物动漫化
  10. CAD鼠标移动到对象时显示对象内容