背景:本文是在小甲鱼数据结构教学视频中的代码的基础上,添加详细注释而完成的。该段代码并不完整,仅摘录了核心算法部分,结合自己的思考,谈谈理解。

Prim算法理解:

如图(摘录自小甲鱼教学视频中的图片),是一个带有权值的连通网。

根据上图可以列写出该连通网的邻接矩阵,为了方便直观的理解:

权值 V0 V1 V2 V3 V4 V5
V0 0 6 1 5
V1 6 0 5 3
V2 1 5 0 7 5 4
V3 5 7 0 2
V4 3 5 0 6
V5 4 2 6 0

如上图所示,实际上Prim算法求解最小生成树的过程就是不断地寻找已走过顶点的最近顶点的过程(边权值最小)。

因此如上图所示,起点在V0点,寻找最近顶点,即V2点;找到V2点后,V2点作为当前顶点,继续寻找最近顶点,这时和已走过的顶点(V0、V2)直接连通的点共有4个:V1、V3、V4、V5,但是显然求解最小生成树不能重复进入已经走过的点,对于这个问题Prim算法采用的方法是将已经走过的点到任何点的权值都设定为0,然后在寻找最短边时,忽略权值为0点边。

这样当我们站在V2点处时,已走过的点到各个点之间的最短权值分别为:

权值 V0 V1 V2 V3 V4 V5
V0、V2 0 5 0 5 5 4

以上叙述的内容其实就是Prim算法的核心,即:①寻找最近点;②迭代lowcost数组。

在实际的算法实现中,就是通过这样一步一步迭代lowcost数组,然后在lowcost数组中寻找最小的权值,作为目标点,最终实现以最短路径遍历连通网。

代码及详细注释:

  1. void MiniSpanTree_Prim(MGraph G)
  2. {
  3. int min,i,j,k;
  4. /* 邻接数组 保存每一个顶点的邻接点(也就是上一个走过的点)的下标 */
  5. int adjvex[MAXWEX];
  6. /* 保存当前顶点向其他顶点的距离(其中已完成的顶点置零,表示不能再走) */
  7. int lowcost[MAXWEX];
  8. lowcost[0] = 0;
  9. adjvex[0] = 0;
  10. /* init */
  11. for(i=1;i<G.numVertexes;i++)
  12. {
  13. /* 将邻接矩阵第0行所有权值先加入数组 */
  14. /* 也就是将生成树的初始位置设定在该顶点 */
  15. /* 注意这个lowcost数组是逐级更新的:迭代到下一个点的时候,更新locwost数组 */
  16. /* lowcost数组更新原则: 已走过的点的lowcost值均保持0(即不再重复进入)
  17. 将当前点到其他点的权值小于lowcost数组的,更新到lowcost数组中(为了保证每一次走的都是最短路径) */
  18. lowcost[i] = G.arc[0][i];
  19. /* 邻接数组初始化为0 */
  20. adjvex[i] = 0;
  21. }
  22. /* the real process creating the minispantree */
  23. for(i=1;i<G.numVertexes;i++)
  24. {
  25. /* min初始化为不可能的值(65535) */
  26. min = INFINITY;
  27. j = 1;
  28. k = 0;
  29. /* 遍历全部顶点 */
  30. while(j<G.numVertexes)
  31. {
  32. /* 找到当前顶点的可行边中权值最小的边 此即当前顶点的下一个邻接点 */
  33. if(lowcost[j] != 0 && lowcost[j] < min)
  34. {
  35. min = lowcost[j];
  36. k = j;
  37. }
  38. j++;
  39. }
  40. /* 打印点与点的邻接关系 遍历完成后这些邻接关系组合在一起就是最小生成树 */
  41. printf("(%d,%d)",adjvex[k],k);
  42. /* 这里很重要 */
  43. /* 将已经走过的顶点对应lowcost数组中的权值置0 已确保不再重复进入 */
  44. lowcost[k] = 0;
  45. /* for循环完成lowcost数组的更新(更新原则在lowcost数组的定义初有详细注释) */
  46. for(j=1;j<G.numVertexes;j++)
  47. {
  48. /* 到已走过的点的权值不更新(保持为0,两行之前的赋值完成) */
  49. /* 邻接矩阵中当前点到其他点的权值小于lowcost数组的更新 */
  50. if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
  51. {
  52. lowcost[j] = G.arc[k][j];
  53. /* 邻接数组赋值(记录各点之间的邻接关系) */
  54. adjvex[j] = k;
  55. }
  56. }
  57. }
  58. }

——cloud over sky

——2020/3/11

最小生成树——Prim算法理解的更多相关文章

  1. 最小生成树——Kruskal算法理解

    背景:本文是在小甲鱼数据结构教学视频中的代码的基础上,添加详细注释而完成的.该段代码并不完整,仅摘录了核心算法部分,结合自己的思考,谈谈理解. Prim算法理解: 如图(摘录自小甲鱼教学视频中的图片) ...

  2. 图论算法(五)最小生成树Prim算法

    最小生成树\(Prim\)算法 我们通常求最小生成树有两种常见的算法--\(Prim\)和\(Kruskal\)算法,今天先总结最小生成树概念和比较简单的\(Prim\)算法 Part 1:最小生成树 ...

  3. 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析

    最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析 最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~ 在考研中呢 ...

  4. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

  5. 最小生成树Prim算法(邻接矩阵和邻接表)

    最小生成树,普利姆算法. 简述算法: 先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中 再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属 ...

  6. 最小生成树—prim算法

    最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...

  7. Highways POJ-1751 最小生成树 Prim算法

    Highways POJ-1751 最小生成树 Prim算法 题意 有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输 ...

  8. SWUST OJ 1075 求最小生成树(Prim算法)

    求最小生成树(Prim算法) 我对提示代码做了简要分析,提示代码大致写了以下几个内容 给了几个基础的工具,邻接表记录图的一个的结构体,记录Prim算法中最近的边的结构体,记录目标边的结构体(始末点,值 ...

  9. 模板——最小生成树prim算法&&向前星理解

    通过最小生成树(prim)和最短路径优化引出的向前星存图,时至今日才彻底明白了.. head[i]存储的是父节点为i引出的最后一条边的编号, next负责把head[i]也就是i作为父节点的所有边连接 ...

随机推荐

  1. 小白,你要的Java抽象类,操碎了心!

    自从给小白写了两篇科普性质的文章后,我就有点一发不可收拾,觉得很有必要继续写下去.因为有读者留言"鼓励"我说,"二哥,你真的是为小白操碎了心啊!"我容易吗?我. ...

  2. 1年之后的拿高工资的资本,Java线程

    只要开启线程,都会开启一块对应的栈内存,然后进行同步执行. -- 谈斌 线程是CPU用来处理程序的资源,线程的执行是抢占式的. 线程开启方式: 创建一个类,继承Thread类.重写 run(), 并在 ...

  3. async与await----js的异步处理

    async与await----js的异步处理 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 之前写代码遇到一个问题,返回 ...

  4. (Lineup the Dominoes筛子)三维状压

    传送门 描述:\(一堆筛子,每个筛子两个面,上面有1-6之间的数字.后一个筛子与前一个筛子的接触面的点数必须相等.\) \(求,有多少种方案堆完筛子.(方案只关心筛子的位置,不关心是否翻转)\) \( ...

  5. 【Linux】1 创建目录:mkdir

    mkdir命令用于创建目录,如同一路径下创建单个或多个目录.递归创建目录,但同路径下不能创建同名目录,且目录名区分大小写. [命令] mkdir [用途] 创建目录(单个目录/多个目录) [语法] m ...

  6. 【编程之美】常用于单片机的接口适配器模式C语言实现

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://www.cnblogs.com/lihuidashen/p/128750 ...

  7. Redis学习笔记(七) 数据库

    Redis 服务器将所有的数据库都保存在服务器状态redisServer结构的db数组中,db数组的每个项都是一个redisDB: struct redisServer{ //一个数组保存着服务器中的 ...

  8. php反序列化(昨天的补充)

    魔术方法 在对PHP反序列化进行利用时,经常需要通过反序列化中的魔术方法,检查方法里是否有敏感操作来进行利用. 常见方法: 创建对象时触发:__construct() 对象被销毁时触发:__destr ...

  9. 改进Page Object公共方法封装(base_page)

    import os from time import sleep from selenium import webdriver from selenium.webdriver.common.by im ...

  10. Centos7 下代理配置

    对于提供服务的服务器来说,一般都配置在内网环境中,而在内网下公司处于安全的考虑,一般不开放外网的访问权限.这时如果想要访问外网,一般需要配置公司提供的代理服务器再进行使用.下面介绍几种配置代理的方法: ...