普里姆算法介绍

普里姆(Prim)算法,是用来求加权连通图的最小生成树的算法。

基本思想

对于图G而言,V是所有顶点的集合;现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G的最小生成树中的边。

从所有u?U,v?(V-U) (V-U表示出去U的所有顶点)的边中选取权值最小的边(u, v),将顶点v加入集合U中,将边(u,

v)加入集合T中,如此不断重复,直到U=V为止,最小生成树构造完毕,这时集合T中包含了最小生成树中的所有边。

普里姆算法图解

以上图G4为例,来对普里姆进行演示(从第一个顶点A开始通过普里姆算法生成最小生成树)。

初始状态:V是所有顶点的集合,即V={A,B,C,D,E,F,G};U和T都是空!

第1步:将顶点A加入到U中。

此时,U={A}。

第2步:将顶点B加入到U中。

上一步操作之后,U={A},

V-U={B,C,D,E,F,G};因此,边(A,B)的权值最小。将顶点B添加到U中;此时,U={A,B}。

第3步:将顶点F加入到U中。

上一步操作之后,U={A,B},

V-U={C,D,E,F,G};因此,边(B,F)的权值最小。将顶点F添加到U中;此时,U={A,B,F}。

第4步:将顶点E加入到U中。

上一步操作之后,U={A,B,F},

V-U={C,D,E,G};因此,边(F,E)的权值最小。将顶点E添加到U中;此时,U={A,B,F,E}。

第5步:将顶点D加入到U中。

上一步操作之后,U={A,B,F,E},

V-U={C,D,G};因此,边(E,D)的权值最小。将顶点D添加到U中;此时,U={A,B,F,E,D}。

第6步:将顶点C加入到U中。

上一步操作之后,U={A,B,F,E,D},

V-U={C,G};因此,边(D,C)的权值最小。将顶点C添加到U中;此时,U={A,B,F,E,D,C}。

第7步:将顶点G加入到U中。

上一步操作之后,U={A,B,F,E,D,C},

V-U={G};因此,边(F,G)的权值最小。将顶点G添加到U中;此时,U=V。

此时,最小生成树构造完成!它包括的顶点依次是:A B

F E D C G。

普里姆算法的代码说明

以"邻接矩阵"为例对普里姆算法进行说明,对于"邻接表"实现的图在后面会给出相应的源码。

1.

基本定义

public class MatrixUDG {

private char[] mVexs; // 顶点集合

private int[][] mMatrix; // 邻接矩阵

private static final int INF = Integer.MAX_VALUE; // 最大值

...

}

MatrixUDG是邻接矩阵对应的结构体。mVexs用于保存顶点,mEdgNum用于保存边数,mMatrix则是用于保存矩阵信息的二维数组。例如,mMatrix[i][j]=1,则表示"顶点i(即mVexs[i])"和"顶点j(即mVexs[j])"是邻接点;mMatrix[i][j]=0,则表示它们不是邻接点。

2.

普里姆算法

/*

* prim最小生成树

*

* 参数说明:

* start -- 从图中的第start个元素开始,生成最小树

*/

public void prim(int start) {

int num = mVexs.length; // 顶点个数

int index=0; // prim最小树的索引,即prims数组的索引

char[] prims = new char[num]; // prim最小树的结果数组

int[] weights = new int[num]; // 顶点间边的权值

// prim最小生成树中第一个数是"图中第start个顶点",因为是从start开始的。

prims[index++] = mVexs[start];

// 初始化"顶点的权值数组",

// 将每个顶点的权值初始化为"第start个顶点"到"该顶点"的权值。

for (int i = 0; i < num; i++ )

weights[i] = mMatrix[start][i];

// 将第start个顶点的权值初始化为0。

// 可以理解为"第start个顶点到它自身的距离为0"。

weights[start] = 0;

for (int i = 0; i < num; i++) {

// 由于从start开始的,因此不需要再对第start个顶点进行处理。

if(start == i)

continue;

int j = 0;

int k = 0;

int min = INF;

// 在未被加入到最小生成树的顶点中,找出权值最小的顶点。

while (j < num) {

// 若weights[j]=0,意味着"第j个节点已经被排序过"(或者说已经加入了最小生成树中)。

if (weights[j] != 0 && weights[j] < min) {

min = weights[j];

k = j;

}

j++;

}

// 经过上面的处理后,在未被加入到最小生成树的顶点中,权值最小的顶点是第k个顶点。

// 将第k个顶点加入到最小生成树的结果数组中

prims[index++] = mVexs[k];

// 将"第k个顶点的权值"标记为0,意味着第k个顶点已经排序过了(或者说已经加入了最小树结果中)。

weights[k] = 0;

// 当第k个顶点被加入到最小生成树的结果数组中之后,更新其它顶点的权值。

for (j = 0 ; j < num; j++) {

// 当第j个节点没有被处理,并且需要更新时才被更新。

if (weights[j] != 0 && mMatrix[k][j] < weights[j])

weights[j] = mMatrix[k][j];

}

}

// 计算最小生成树的权值

int sum = 0;

for (int i = 1; i < index; i++) {

int min = INF;

// 获取prims[i]在mMatrix中的位置

int n = getPosition(prims[i]);

// 在vexs[0...i]中,找出到j的权值最小的顶点。

for (int j = 0; j < i; j++) {

int m = getPosition(prims[j]);

if (mMatrix[m][n]

min = mMatrix[m][n];

}

sum += min;

}

// 打印最小生成树

System.out.printf("PRIM(%c)=%d: ", mVexs[start], sum);

for (int i = 0; i < index; i++)

System.out.printf("%c ", prims[i]);

System.out.printf("\n");

}

普里姆算法的源码

这里分别给出"邻接矩阵图"和"邻接表图"的普里姆算法源码。

原文:http://www.cnblogs.com/skywang12345/p/3711510.html

prim算法详解java_Prim算法(三)之 Java详解相关推荐

  1. kruskal java_Kruskal算法(三)之 Java详解

    最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总和 ...

  2. java邻接表无向图的创建_邻接表无向图(三) 之Java详解

    前面分别介绍了邻接表无向图的C和C++实现,本文通过Java实现邻接表无向图. 目录 邻接表无向图的介绍 邻接表无向图是指通过邻接表表示的无向图. 上面的图G1包含了"A,B,C,D,E,F ...

  3. Unicode双向算法详解(bidi算法)(三)

    Unicode双向算法详解(bidi算法)(三) 本文为原创文章,转载请注明出处,或注明转载自"黄邦勇帅(原名:黄勇) 本文是对<C++语法详解>一书相关章节的增补,以增强读者对 ...

  4. 详解二叉树的三种遍历方式(递归、迭代、Morris算法)

    详解二叉树的三种遍历方式(递归.迭代.Morris算法) 最重要的事情写在前面:遍历顺序不一定就是操作顺序!!! 递归解法 首先,一颗二叉树它的递归序列是一定的,导致其前中后序不同的原因只不过是访问节 ...

  5. Java虚拟机详解04----GC算法和种类【重要】

    本文主要内容: GC的概念 GC算法  引用计数法(无法解决循环引用的问题,不被java采纳) 根搜索算法 现代虚拟机中的垃圾搜集算法: 标记-清除 复制算法(新生代) 标记-压缩(老年代) 分代收集 ...

  6. 【算法知识】详解堆排序算法

    点击蓝色字关注我们! 什么是堆 「堆」首先是一个完全二叉树,「堆」分为「大顶堆」和「小顶堆」: 「大顶堆」 : 每个节点的值大于或等于其左右孩子节点的值,称为大顶堆. 「小顶堆」同理就是每个节点的值小 ...

  7. 【算法知识】详解快速排序算法

    基本思想 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 本文的思路是以从小到大为例讲的. 快速排序的基本思想是任取待排序序列的一个元素作为中心元素 ...

  8. Java虚拟机详解04----GC算法和种类

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  9. 克鲁斯卡尔算法c语言,Kruskal算法(一)之 C语言详解

    最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总和 ...

最新文章

  1. 推荐几个(抖音/阿里/腾讯)年薪100W大佬的硬核公众号
  2. 使用json-lib实现json to javabean
  3. 大学计算机基础课程报告python-基于Python的“大学计算机基础”课程教学设计.doc...
  4. Big Data Exchange宣布在南京建设数据中心
  5. 2018年东北农业大学春季校赛 F wyh的集合【思维】
  6. VTK:可视化之HideActor
  7. [高中作文赏析]相约
  8. [原]RHCS集群的服务切换测试札记
  9. 计算机网络技术放块队解说词,基于《计算机网络技术》课程多媒体课件制作与设计.doc...
  10. 社会对IT 从业人员综合素质的需求
  11. Django魔术用法
  12. 找不出破绽!斯坦福等新研究:随意输入文本,改变视频人物对白,逼真到让作者害怕...
  13. Linux中的压缩命令
  14. leaflet虚线(leaflet篇.60)
  15. Android Studio模拟器AndroidWifi连接成功但无法访问网络问题
  16. python车牌识别系统抬杆_车牌识别系统识别到道闸不抬杆是什么问题?
  17. uniapp怎么调起摄像头拍视频_uniapp如何实现直播
  18. 记一次子线程Thread.sleep影响主线程的坑
  19. python语法糖 -- 列表正负数的排序
  20. 蓝白屌丝卡过NAXX蜘蛛区英雄模式

热门文章

  1. Leetcode每日一题:83.remove-duplicates-from-sorted-list(删除排序链表中的重复元素)
  2. 【2019-06-26】改变的开始
  3. excel 汇总 mysql_利用mysql收集excel录入汇总
  4. tf卡量产工具万能版_手上还有SD卡/TF卡的小伙伴,这些玩法你有关注过吗
  5. bind_param 类怎么写_情感类自媒体怎么写?你不知道的情感类文章4大禁忌!
  6. fiddler如何显示IP地址栏?
  7. 2019新悦动打火困难解决了吗_悦动大面积存在启动困难北京现代检查不出原因就换零件...
  8. Android5.1自定义闹钟铃声,Android 设置来电铃声、通知铃声、闹钟铃声中的坑
  9. mysql 5.7 plugin 安装_mysql5.7以上版本安装
  10. python中哪些是无序_Python笔记 【无序】 【三】