C语言实现图的最小生成树算法: Kruskal算法详解
C语言实现图的最小生成树算法: Kruskal算法详解
这篇文章将介绍如何使用C语言实现 Kruskal 算法来寻找一个无向图的最小生成树。
什么是最小生成树?
在一个无向图中,最小生成树(MST)是指连接所有节点且总边权值最小的树。换句话说,它是连接图中所有节点的边的子集,且该子集不包含循环,并且所有边的权值之和最小。
Kruskal算法
Kruskal 算法是一种贪心算法,用于查找加权无向图的最小生成树。其基本步骤如下:
- 创建一个包含图中所有边的集合,并按边权值升序排序。2. 创建一个空的 MST 集合。3. 遍历排序后的边集合: * 如果当前边连接的两个节点不在同一个连通分量中,则将该边添加到 MST 集合中,并将这两个节点所在的连通分量合并。 * 否则,丢弃当前边。4. 重复步骤3,直到 MST 集合包含 (V-1) 条边,其中 V 是图中节点的数量。
C语言代码实现c#include <stdio.h>#include <stdlib.h>
// 定义边的结构体typedef struct Edge { int tail; // 边的起点 int head; // 边的终点 int weight; // 边的权值} Edge;
// 并查集查找操作int find(int parent[], int i) { if (parent[i] == i) { return i; } return find(parent, parent[i]);}
// 并查集合并操作void unionSet(int parent[], int x, int y) { int xroot = find(parent, x); int yroot = find(parent, y); parent[xroot] = yroot;}
// 比较函数,用于对边进行排序int compare(const void *a, const void *b) { return ((Edge *)a)->weight - ((Edge *)b)->weight;}
// Kruskal算法实现void kruskal(Edge edges[], int edgeNum, int nodeNum) { // 初始化 int parent[nodeNum]; for (int i = 0; i < nodeNum; i++) { parent[i] = i; }
// 用于存储被删除的边 Edge removedEdges[edgeNum]; int removedEdgeNum = 0;
// 用于存储最小生成树的边 Edge mstEdges[nodeNum - 1]; int mstEdgeNum = 0;
// 对边进行排序 qsort(edges, edgeNum, sizeof(Edge), compare);
// 遍历所有边 for (int i = 0; i < edgeNum && mstEdgeNum < nodeNum - 1; i++) { Edge e = edges[i]; int x = find(parent, e.tail); int y = find(parent, e.head); // 如果这条边不会形成环 if (x != y) { // 将这条边加入最小生成树 mstEdges[mstEdgeNum++] = e; // 合并两个连通分量 unionSet(parent, x, y); } else { // 否则,将这条边加入删除的边数组中 removedEdges[removedEdgeNum++] = e; } }
// 输出删除的边 printf('删除的边:
'); for (int i = 0; i < removedEdgeNum; i++) { Edge e = removedEdges[i]; printf('(%d, %d) 权值为 %d ', e.tail, e.head, e.weight); }}
int main() { // 图的边 Edge edges[] = { {0, 1, 10}, {0, 2, 6}, {0, 3, 5}, {1, 3, 15}, {2, 3, 4} }; int edgeNum = sizeof(edges) / sizeof(edges[0]); int nodeNum = 4;
// 调用Kruskal算法 kruskal(edges, edgeNum, nodeNum);
return 0
原文地址: https://www.cveoy.top/t/topic/fXt1 著作权归作者所有。请勿转载和采集!