各位看官们,大家好,上一回中咱们说的是使用克鲁斯卡尔算法生成最小生成树的例子,这一回咱们说的
例子是:使用普里姆算法生成最小生成树。闲话休提,言归正转。让我们一起talk C栗子吧!
普里姆(Prim)算法的基本思路:在图中任意取一个顶点,查找与该顶点相连的边中,权值最小的一条边和
该边上的顶点。把找到的点放到一棵树中,然后重复该过程,直到图中所有点都被查找完为止。这个时候,
存放查找到点的树就是一棵最小生成树。在理解普里姆算法时,有一点必需明白:两点之间的权值不一定是
这两点之间的最小权值,可能通过其它点找到两点之间的最小权值。
普里姆算法的实现步骤:
- 1.选取图中第一个顶点作为起点(选择是任意的,可以自己定义哪个顶点作为起点);
- 2.从图的邻接矩阵中读取与起点相连边的权值,并且存放到一个数组中;
- 3.在数组中找到权值最小的边,并且把该边的另外一个顶点当作新的起点;
- 4.修改步骤2中的数组,把新起点在数组中对应的权值修改为0,表示该点存放到树中了;
- 5.从图的邻接矩阵中读取与新起点相连边的权值;
- 6.如果该权值比步骤2数组中该点的权值小,那么更新数组中该点的权值;
- 7.重复步骤3到步骤6,直到图中所有点都被查找完为止;
看官们,正文中就不写代码了,详细的代码放到了我的资源中,大家可以点击这里下载使用。在代码中我
们专门使用一个数组来存放各个顶点的权值,其实该数组存放的是起点与该位置顶点之间的最小权值,例
如:a[1]=3表示起点(我们开始选取了编号为0的顶点当作起点)与编号为1的顶点之间最小权值为3。程
序中通过不断地修改该数组来寻找两个顶点之间的最小权值。该数组是一个核心数组,通过该数组大家就
能发现我刚才告诉大家的内容是多么地重要:两点之间的权值不一定是这两点之间的最小权值,可能通过
其它点找到两点之间的最小权值。如果大家不容易理解这句话的含义,那么从下面的图形中找个例子来进
行分析。例如:E和F之间有一条权值为10的边,我们可以把10当作E和F两点之间的权值,但是10不是它
们之间的最小权值,如果从E-C-F这个路径去计算它们之间的权值,那么E和F之间的权值为1+2=3,3才是
它们之间的最小权值。
另外,在程序中我们还专门定义了一个数组用来存放各个顶点的编号,定义它的主要目的是为了显示顶点
之间的连接关系。该数组的意义比较特殊,我们也来说明一下,例如:a[1]=3表示编号为3的顶点和编号
为1的顶点之间有一条边,该边上的权值为顶点3和顶点1之间的最小权值。我们在程序中打印出了该数组中
各个元素的值,大家可以自己体会一下。
下面是程序的运行结果以及程序中使用的图和该图最小生成树的截图。大家可以通过对比的方式查看程序
运行结果和截图,这样可以更好地理解程序的原理。
下面是程序的运行结果截图:
<span style="font-family:SimSun;">运行结果中,有两行,我添加了注释,请参考</span>
--- Show the Minimum Spanning Tree of Graph---
[A-B][A-D][D-G][G-H][H-F][F-C][C-E] <span style="color:#3366FF;"> //最小生成上的各个边</span>
0-0-5-0-2-7-3-6- <span style="color:#3366FF;"> //打印存放最小生成树顶点数组中各个元素的值</span>
下面是程序中使用的图以及该图的最小生成树:
(程序中使用的图) (该图的最小生成树)
各位看官,关于最小生成树的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解。