目录
1.什么是生成树?
2.最小生成树
而对于最小生成树的算法实现有两种,一种Prim,另一种Kruskal算法。
3.Prim算法(普里姆)
3.1算法思想
3.2代码实现(核心代码)
int prim(int pos)
{
dist[pos] = 0;
// 一共有 n 个点,就需要 遍历 n 次,每次寻找一个权值最小的点,记录其下标
for(int i = 1; i <= n; i ++)
{
int cur = -1;
for(int j = 1; j <= n; j ++)
{
if(!vis[j] && (cur == -1 || dist[j] < dist[cur]))
{
cur = j;
}
}
// 这里需要提前终止
if(dist[cur] >= INF) return INF;
sum += dist[cur];
vis[cur] = 1;
for(int k = 1; k <= n; k ++)
{
// 只更新还没有找到的最小权值
if(!vis[k]) dist[k] = min(dist[k],a[cur][k]);
}
}
return sum;
}
4.Kruskal算法(克鲁斯卡尔)
4.1算法思想
4.2代码实现(核心代码)
void MiniSpanTree_Kruskal(EdgeGraph *E)
{
int i;
int num;//生成边计数器,当num=顶点数-1 就代表最小生成树生成完毕
int root1,root2;
int LocVex1,LocVex2;
int parent[VertexMax];//用于查找顶点的双亲,判断两个顶点间是否有共同的双亲,来判断生成树是否会成环
//1.按权值从小到大排序
sort(E);
print(E);
//2.初始化parent数组
for(i=0;i<E->vexnum;i++)
{
parent[i]=-1;
}
printf("\n 最小生成树(Kruskal):\n\n");
//3.
for(num=0,i=0;i<E->edgenum;i++)
{
LocVex1=LocateVex(E,E->edge[i].begin);
LocVex2=LocateVex(E,E->edge[i].end);
root1=FindRoot(LocVex1,parent);
root2=FindRoot(LocVex2,parent);
if(root1!=root2)//若不会成环,则在最小生成树中构建此边
{
printf("\t\t%c-%c w=%d\n",E->edge[i].begin,E->edge[i].end,E->edge[i].weight);//输出此边
parent[root2]=root1;//合并生成树
num++;
if(num==E->vexnum-1)//若num=顶点数-1,代表树生成完毕,提前返回
{
return;
}
}
}
}