1.Prim算法
该算法的核心思想就是在图中所有的边权值列出来TE,再找一端固定(自己设定)U={u…}的点集合,另一端v不在点集合中的权值最小的边,然后将该边并入集合TE中,并且将v并入U集合中,重复该步骤直到所有的点都在U中,就完成一个最小生成树的构建。
void MiniSpanTree_Prim(MGraph G)
{
int min, i, j, k;
int adjvex[MAXVEX]; //保存相关顶点下标
int lowcost[MAXVEX]; //保存相关顶点间边的权值
lowcost[0] = 0; //先将下标0的点设置为最小生成树的元素
adjvex[0] = 0; //初始化第一个顶点下标为0
for (i = 1; i < G.numVertexes; i++)
{
lowcost[i] = G.arc[0][i]; //设置以下标0为端点有边的权值
adjvex[i] = 0;
}
for (i = 0; i < G.numVertexes; i++)
{
min = INFINITY_l;
j = 1; k = 0;
while (j < G.numVertexes) //循环遍历
{
if (lowcost[j] < min && lowcost != 0)
{
min = lowcost[j];
k = j; //将最小值下标储存到k中
}
j++;
}
cout << adjvex[k]<<',' << k << endl; //输出最小生成树中的一条边
lowcost[k] = 0; //将下标为k的元素设置为0表明该点已经在生成树中
for (j = 1; j < G.numVertexes; j++)
{
if (lowcost[j] != 0 && G.arc[k][j] < lowcost[j]) //继续比较,如果有更小的权值,将其更改
lowcost[j] = G.arc[k][j];
adjvex[j] = k; //将其端点设置为k
}
}
}
2.Kruskal算法
Prim是基于点来构建树的,而Kruskal是基于边来构建树的,将权值按照由大到小排列,并且找出对应权值的边的两个端点,不断寻找最小权值的边来构建树
以下是实现代码
typedef struct
{
int begin; //端点
int end; //端点
int weight; //权值
}Edge; //边结点
/*Kruskal算法生成最小生成树*/
void MiniSpanTree_Kruskal(Graph G)
{
int i, n, m;
Edge edges[MAXEDGE]; //建立边集数组
int parent[MAXVEX]; //定义一数组用来判断边与边是否形成环路
for (i = 0; i < G.numVertexes; i++)
{
parent[i] = 0; //初始化为0
}
for (i = 0; i < G.numVertexes; i++)
{
n = Find(parent, edge[i].begin);
m = Find(parent, edges[i].end);
if (n != m) //假如n与m不等,说明此边没有与现有生成树形成环路
{
parent[n] = m; //表示将此顶点放入最小生成树集合中
cout << edges[i].begin << edges[i].end << edges[i].weight << endl;
}
}
}
int Find(int *parent int f)
{
while (parent[f] > 0)
f = parent[f];
return f;
}