具体理论什么的我就不说了,网上有很多,讲的都很好,我就简单总结一下,我们设两个集合,一个是最小生成树集合T,另一个是图Graph,我们选取 集合Graph-集合T 距集合T中顶点最近的顶点 加入后,更新与刚加入顶点相连的顶点权值,这样不断重复,直到集合T顶点==图Graph中顶点。
已选那一栏就是我们上面说的集合T,可选与不可选两列和是图Graph-集合T.
代码详解:
#include <iostream>
#include <memory.h>
using namespace std;
#define MAXVEX 9 //节点最大值
#define myINFINITY 2139062143 //自定义无穷
int Graph[MAXVEX][MAXVEX]; //二维数组存边
void Prim() {
memset( Graph, 127, sizeof( Graph ) ); //初始化所有边为 无穷大
int closest[MAXVEX];//adjevx[4]=0 代表目前最小生成树中节点4的前驱节点是0
//lowcost[i]=18 代表节点i到目前最小生成树的最短距离18
//当lowcost[i]=0 时表示此下标的顶点纳入最小生成树
int lowcost[MAXVEX];
lowcost[0] = 0; //同上 v0加入最小生成树
closest[0] = 0; //设V0 前驱节点还是v0
//初始化,循环除下标0外的所有节点
for( int i = 1; i < MAXVEX; i++ ) {
lowcost[i] = Graph[0][i]; //更新所有与顶点v0有边的权值
closest[i] = 0; //初始化所有节点的前驱为v0
}
//往最小生成树中添加节点,需要添加MAXVEX-1个节点
for( int i = 1; i < MAXVEX; i++ ) {
int min = myINFINITY; //初始化最小权值为无穷
int j = 1; //顶点序号,节点v0已加入,从1开始
int k = 0; //存当前权值最小顶点下标
//找不在最小生成树中且权值最小的顶点(与最小生成树中节点相连)
while( j < MAXVEX ) {
//找不在最小生成树中且权值最小的顶点(与最小生成树中节点相连)
if( lowcost[j] != 0 && lowcost < min ) {
min = lowcost[j]; //更新最小权值
k = j; //存当前权值最小顶点下标
}
j++;
}
//上面找出了即将加入最小生成树的顶点,下面输出含这个顶点的最小权值边
cout << closest[k] << "-" << k << endl;
lowcost[k] = 0; //lowcost=0,说明此顶点已加入最小生成树
//更新与顶点k相连的边的权值
for( int j = 1; j < MAXVEX; j++ ) {
//顶点j未加入最小生成树且 与k节点相连的权值比以前还要小
if( lowcost[j] != 0 && Graph[k][j] < lowcost[j] ) {
lowcost[j] = Graph[k][j]; //更新权值
closest[j] = k; //更新前驱节点
}
}
}
}