首页 > 代码库 > Kruskal算法的C语言实现(并查集版)
Kruskal算法的C语言实现(并查集版)
【问题】
Kruskal算法求加权连通图的最小生成树的算法。kruskal算法总共选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。注意到所选取的边若产生环路则不可能形成一棵生成树。kruskal算法分e 步,其中e 是网络中边的数目。按耗费递增的顺序来考虑这e 条边,每次考虑一条边。当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。
【代码】
#include <stdio.h> #include <stdlib.h> #define MAX 20 typedef char Vertextype; typedef struct edge { int begin; int end; int weight; }Edge; typedef struct { int weight; }Adjmatrix[MAX][MAX]; typedef struct { Vertextype vertexs[MAX]; Adjmatrix arc; int vexnum, arcnum; }MGraph; void creategraph(MGraph &G, Edge *edges); int locadvex(MGraph G, Vertextype v); int find(int *parent, int p); void unionfind(int *parent, int *rank, int p, int q); void sort(Edge *edges, int n); void kruskal(MGraph G, Edge *edges); int locadvex(MGraph G, Vertextype v) { int i = 1; while(v != G.vertexs[i]) i++; return i; } void creategraph(MGraph &G, Edge *edges) { int i, j, n, m; Vertextype beginvex, endvex; int weight; printf("请输入顶点数和边数:\n"); scanf("%d%d", &G.vexnum, &G.arcnum); getchar(); //顶点输入 for(i = 1; i <= G.vexnum; i++) { printf("%d:", i); scanf("%c", &G.vertexs[i]); getchar(); } //输入边和权值 for(i = 1; i <= G.arcnum; i++) { printf("%d(A,B,20):", i); scanf("%c",&beginvex); getchar(); scanf("%c", &endvex); getchar(); scanf("%d", &weight); getchar(); n = locadvex(G, beginvex); m = locadvex(G, endvex); G.arc[n][m].weight = weight; edges[i].weight = weight; edges[i].begin = n; edges[i].end =m; } } void sort(Edge *edges, int n) { int i, j; int tmp; for(i = 1; i <= n-1; i++) for(j = i+1; j <= n; j++) if(edges[j].weight < edges[i].weight) { tmp = edges[i].begin; edges[i].begin = edges[j].begin; edges[j].begin = tmp; tmp = edges[i].end; edges[i].end = edges[j].end; edges[j].end = tmp; tmp = edges[i].weight; edges[i].weight = edges[j].weight; edges[j].weight = tmp; } } int find(int *parent, int p) { while(p != parent[p]) { p = parent[p]; } return p; } void unionfind(int *parent, int *rank, int p, int q) { int i, j; i = find(parent, p); j = find(parent, q); if(i == j) return; if(rank[i] < rank[j]) { parent[i] = j; rank[j] += rank[i]; } else { parent[j] = i; rank[i] += rank[j]; } } void kruskal(MGraph G, Edge *edges) { int i, j, n, m; int sum = 0; int parent[MAX], rank[MAX]; //初始化 for(i = 1; i <=G.arcnum; i++) { parent[i] = i; rank[i] = 1; } //边权重排序 sort(edges, G.arcnum); for(i = 1; i <= G.arcnum; i++) { n = find(parent, edges[i].begin); m = find(parent, edges[i].end); if( n != m) { printf("<< %d, %d >> %d\n", edges[i].begin, edges[i].end, edges[i].weight); unionfind(parent, rank, n, m); sum += edges[i].weight; } } } int main(int argc, char const *argv[]) { MGraph G; Edge edges[MAX]; creategraph(G, edges); kruskal(G, edges); getchar(); return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。