首先,什么是最小生成树呢
在图那里有一个概念:一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边。我们把构造连通图的最小代价生成树称为最小生成树。
以下图为例,先创建邻接矩阵
Prim算法
我个人的理解,Prim算法就是在一个图中,从任意点开始循环访问所有的点找出最小的权值,这就是最小生成树的第一条边,接着从这条边的两端顶点依次访问邻接顶点,并比较每条边的权值找出代价最小的边,直到形成一个连通图。
下面给出代码
首先是邻接矩阵的创建
struct Graph
{
char vex;
int arc[max_][max_];
int vexnum, edgenum;
};
Graph G;
void CreateG(void) //================建立邻接矩阵
{
int i, j, a, n;
cin >> G.vexnum >> G.edgenum;
for (i = 0; i < G.vexnum; i++)
for (j = 0; j < G.edgenum; j++)
{
if (i == j)
G.arc[i][j] = 0;
else
G.arc[i][j] = MAX;
}
for (a = 0; a < G.edgenum; a++)
{
cin >> i >> j >> n;
G.arc[i][j] = n; G.arc[j][i] = n;
}
}
接着是Prim算法
void MiniSpanTree_Prim()
{
int min, i, j, k, s = 0, m = 0, a[MAX];
int adj[MAX];
int Low[MAX];
Low[0] = 0; adj[0] = 0;
for (i = 1; i < G.vexnum; i++)
{
Low[i] = G.arc[0][i];
adj[i] = 0;
}
for (i = 1; i < G.vexnum; i++)
{
min = MAX;
j = 1; k = 0;
while (j < G.vexnum)
{
if (!Low[j] && Low[j]<min)
{
min = Low[j];
k = j;
}
j++;
}
Low[k] = 0;
for (j = 1; j < G.vexnum; j++)
{
if (!Low[j] && G.arc[k][j])
{
Low[j] = G.arc[k][j];
adj[j] = k;
}
}
}
}
接着我们来说说Kruskal算法
Prim算法是以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的。而Kruskal算法是以边为目标去构建的,因为权值就是在边上的,但是要考虑是否会形成环路。所以就需要用到边集数组结构(另一种图的存储结构)
边集数组的创建
将邻接矩阵转换为边集数组
for (i = 0; i < G.vexnum; i++)
for (j = 0; j < i; j++)
{
if (G.arc[i][j] != 0 && G.arc[i][j] != MAX)
{
edges[a].begin = j;
edges[a].end = i;
edges[a].weight = G.arc[i][j];
a++;
}
}
for(i=0;i<G.vexnum;i++)
for (j = i+1; j < G.vexnum; j++)
{
if (edges[i].weight > edges[j].weight)
{
tmp = edges[i].weight;
edges[i].weight = edges[j].weight;
edges[j].weight = tmp;
}
}
Kruskal算法
int find(int *parent, int f)
{
while (parent[f] > 0)
f = parent[f];
return f;
}
void Mini_Kruskal()
{
int i, n, m;
int parent[MAXVEX];
for (i = 0; i < G.vexnum; i++)
parent[i] = 0;
for (i = 0; i < G.vexnum; i++)
{
n = find(parent, edges[i].begin);
m = find(parent, edges[i].end);
if (n != m)
{
parent[n] = m;
cout << edges[i].begin << edges[i].end << edges[i].weight;
}
}
}
在Kruskal算法中,我们只关注边的权值,每次都访问最小的边,并用数组parent判断是否形成环路。接着循环下去直到所有顶点都在同一连通分量上为止。