#include<stdio.h>
//构造边的数据类型,包括起点终点权值
struct Edgetype {
int from;
int to;
int weight;
};
//少用宏定义
const int MAXvertex = 10;
const int MAXedge = 100;
//构造图的结构体,包括用来储存顶点信息的数组ver和边信息的表数组edgetable
struct Graph {
char ver[MAXvertex];
Edgetype edgetable[MAXedge];
int vertexnum, edgenum;
};
//创建一个图
void Creatgraph(Graph& g,char str[],int vnum,int ednum)
{
g.edgenum = ednum;
g.vertexnum = vnum;
for(int i=0;i<g.vertexnum;i++)
g.ver[i] = str[i];
//初始化边表
//没学插入排序所以先按顺序输入,学了可以改进一下
printf("注意:请按边的权值由小到大依次输入信息\n");
for (int i = 0; i < g.edgenum; i++)
{
int v1, v2, power;
printf("请输入一条边的两个顶点的序号以及边的权值:\n");
scanf_s("%d,%d,%d", &v1, &v2,&power);
g.edgetable[i].from = v1;
g.edgetable[i].to = v2;
g.edgetable[i].weight = power;
}
}
//寻根函数(确切来说应该是寻祖宗,因为找到的结点往往跟线索结点不相连)
int Findroot(int b[],int a)
{
int t = a;
while (b[t]> -1)
t = b[t];
return t;
}
void Kruskal( Graph g)
{
//初始化辅助parent数组
int parent[MAXvertex];
int num = 0;
for (int i = 0; i < g.vertexnum; i++)
parent[i] = -1;
for (int i = 0; i < g.edgenum; i++)
{
//找到边的两个顶点的祖宗结点
int vex1 = Findroot(parent,g.edgetable[i].from);
int vex2 = Findroot(parent, g.edgetable[i].to);
//不一样说明两个顶点不在同一个连通分量上,不构成回路,可连接
if (vex1 != vex2)
{
//输出这条边
printf("(%d,%d)%d\n", g.edgetable[i].from, g.edgetable[i].to, g.edgetable[i].weight);
//将一个连通分量的根节点作为另一个连通分量的根节点的根节点,从而合并两个连通分量并使根节点唯一
parent[vex2] = vex1;
num++;
//若边数达到n-1则已经生产了一棵树,可结束运行
if (num == g.vertexnum)
return;
}
}
}
int main()
{
char a[] = "ABCDEF";
Graph g;
Creatgraph(g,a,6,9);
Kruskal(g);
}
运行示例图如下