C语言编程实现Kruskal算法,解决如下无向连通有权图的最小生成树问题,在控制台窗口输出最小生成树的边
时间: 2023-07-22 11:41:10 浏览: 83
好的,我可以为您编写Kruskal算法的C语言实现。假设给出的无向连通有权图为一个邻接矩阵,下面是代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100 // 最大顶点数
#define INF 32767 // 表示无穷大
typedef struct {
int u; // 边的起始顶点
int v; // 边的终止顶点
int w; // 边的权重
} Edge;
Edge edges[MAX_VERTEX_NUM * (MAX_VERTEX_NUM - 1) / 2]; // 边集数组
int parent[MAX_VERTEX_NUM]; // 并查集数组
// 比较函数,按照边权从小到大排序
int cmp(const void* a, const void* b) {
Edge* ea = (Edge*)a;
Edge* eb = (Edge*)b;
return ea->w - eb->w;
}
// 查找并查集的根节点
int find(int x) {
int root = x;
while (parent[root] != -1) {
root = parent[root];
}
return root;
}
// Kruskal算法
void Kruskal(int n, int e, Edge edges[]) {
int i, j, k;
int sum = 0; // 最小生成树的总权值
int count = 0; // 已选的边的数量
for (i = 0; i < n; i++) {
parent[i] = -1; // 初始化并查集
}
qsort(edges, e, sizeof(Edge), cmp); // 对边集数组排序
printf("最小生成树的边为:\n");
for (i = 0; i < e; i++) {
int u = edges[i].u;
int v = edges[i].v;
int w = edges[i].w;
int r1 = find(u); // 查找u所在的连通分量
int r2 = find(v); // 查找v所在的连通分量
if (r1 != r2) { // 如果不在同一连通分量中,说明可以加入最小生成树
printf("(%d, %d, %d)\n", u, v, w);
sum += w;
parent[r1] = r2; // 合并连通分量
count++;
if (count == n - 1) { // 边数达到n-1时,最小生成树已经构建完成
break;
}
}
}
printf("最小生成树的总权值为:%d\n", sum);
}
int main() {
int n, e; // n为顶点数,e为边数
int i, j, k;
printf("请输入顶点数和边数:\n");
scanf("%d%d", &n, &e);
printf("请输入各边的起始顶点、终止顶点和权值:\n");
for (i = 0; i < e; i++) {
scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w);
}
Kruskal(n, e, edges);
return 0;
}
```
在控制台窗口中,程序会先提示输入顶点数和边数,然后再提示输入各边的起始顶点、终止顶点和权值。程序会按照边权从小到大的顺序输出最小生成树的边,以及最小生成树的总权值。
阅读全文