前言
普里姆算法是找到最小生成树,通俗的讲,就是通向各点的最短路径,它和最短路径算法不同之处就是,最小生成树更关注大局,强调大局之间是最短路径。 它的思想是从任一点除法,选取离它最近的一点,再从该点选取除这两点之外的任一点,直到没有剩余。普利姆算法注释已经很详细了,原理不做深究,请自行复习。注:本文的实验案例都是清华大学严蔚敏老师数据结构视频中所讲解的案例,所以本类的文章是十分适合大家对课上知识加深认识的。测试案例和源代码将会在文末给出。
算法
本算法的存储结构为邻接矩阵,类型声明如下:typedef struct _graph {
int matrix[MAX][MAX];//二维数组表示的矩阵
char vexs[MAX];//顶点集
int vexnum;//顶点个数
int edgnum;//边的个数
}Graph, *pGraph;//邻接矩阵的存储结构,用pGraph指针指向
下面是算法本体
void prim(Graph*gra,char v0) {
int n = gra->vexnum;
int k = getPosition(gra, v0);
vector<vector<int>> close(n, vector<int>(n));//第一个数为从哪个点来,第二个为该点到其余点的直接路径长度
vector<bool> isvisited(n,true);
//初始化从k到其他点的路径
for (int i = 0; i < n; i++) {
close[k][i] = gra->matrix[k][i];
}
isvisited[k] = false;//将k加入u集
for (int i = 1; i < n; i++) {//对剩余的n-1条路径进行操作
int min = INF, v;
for (int j = 0; j < n; j++) {//选择从k到v-u集中最短的一条
if (isvisited[j] && k != j && gra->matrix[k][j] < INF) {//首先保证从v-u集里选元素,然后再选除自身外的最小的路径
v = j;
min = gra->matrix[k][j];
}
}
isvisited[v] = false;
cout << gra->vexs[k] << " " << gra->vexs[v] << endl;
k = v;
}
}
上机须知
|
对应的邻接矩阵
0 4 2 * * * * *
* 0 3 5 9 * * *
* * 0 5 * * * 5
* * * 0 7 6 * 4
* * * * 0 3 * *
* * * * * 0 2 *
* * * 6 * * 0 *
* * * * * * 6 0
在我给出的测试源码里需要输入以下内容,直接粘贴就可以
8
14
a
b
c
d
e
f
g
h
a b 4
a c 2
b e 9
b d 5
b c 3
c d 5
c h 5
d e 7
d h 4
e f 3
f g 2
g d 6
d f 6
h g 6
源码地址:点击这里