C语言-数据结构-克鲁斯卡尔kruskal

#include <stdio.h>
#include <stdlib.h>
//#include "ljjz.h"
//求解最小生成树算法
typedef struct edgedata
{
    int beg,en;///边顶点序号
    int length;///边的权值长
}edge;
///对边向量快速排序
///边向量edges边向量左右下标left right
void QuickSort(edge edges[],int left,int right)
{
    edge x;
    int i,j,flag=1;
    if(left<right)
    {
        i=left;
        j=right;
        x=edges[i];
        while(i<j)
        {
            while(i<j&&x.length<edges[j].length)
                j--;
            if(i<j)
             edges[i++]=edges[j];
             while(i<j&&x.length>edges[i].length)
                i++;
             if(i<j)
             edges[j--]=edges[i];
        }
        edges[i]=x;
        QuickSort(edges,left,i-1);
        QuickSort(edges,i+1,right);
    }
}
///从图g邻接矩形读所有边信息
///邻接矩阵g 边向量edges
void GetEdge(Mgraph g,edge edges[])
{
    int i,j,k=0;
    for(i=0;i<g.n;i++)
      for(j=0;j<i;j++)
       if(g.edges[i][j]!=0&&g.edges[i][j]<FINITY)
       {
           edges[k].beg=i;
           edges[k].en=j;
           edges[k++].length=g.edges[i][j];
       }
}
///kruskal求解最小生成树算法
void kruskal(Mgraph g)
{
    int i,j,k=0,ltfl;
    int cnvx[M];
    edge edges[M*M];  ///存放图所有边
    edge tree[M];   ///最小生成树边信息
    GetEdge(g,edges);///读取所有边
    QuickSort(edges,0,g.e-1);///对边进行升序排序
    for(i=0;i<g.n;i++)
    {
        cnvx[i]=i;   ///设置每个顶点的连通分量为顶点编号
    }
    for(i=0;i<g.n-1;i++)  ///树中g.n-1条边
    {
        while(cnvx[edges[k].beg]==cnvx[edges[k].en])
            k++;    ///找到属于两个连通分量权最小边
        tree[i]=edges[k];   ///将k边加入到生成树中
        ltfl=cnvx[edges[k].en];///记录选中边的连通分量编号
        for(j=0;j<g.n;j++)      ///两个连通分量合并一个
            if(cnvx[j]==ltfl)
                cnvx[j]=cnvx[edges[k].beg];
            k++;
    }
    printf("min tree:");
    for(j=0;j<g.n-1;j++)
    {
        printf("c---%c%6d\n",g.vexs[tree[j].beg],g.vexs[tree[j].en],tree[j].length);
    }
}
void main()
{
    Mgraph g;
    char filename[20];
    printf("please input filename of Graph:");
    gets(filename);///读取图输入文件
    creat(&g,filename,0);  ///创建邻接矩阵
    kruskal(g);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
克鲁斯卡尔算法是一种解决最小生成树问题的算法,可以用来求解带权连通图的最小生成树。下面是使用C语言实现克鲁斯卡尔算法的数据结构代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_VERTEX_NUM 100 // 最大顶点数 #define MAX_EDGE_NUM (MAX_VERTEX_NUM * (MAX_VERTEX_NUM - 1) / 2) // 最大边数 // 边的结构体 struct Edge { int start; // 起点 int end; // 终点 int weight; // 权值 }; // 图的结构体 struct Graph { int n; // 顶点数 int m; // 边数 struct Edge edges[MAX_EDGE_NUM]; // 存储边的数组 }; // 并查集 int fa[MAX_VERTEX_NUM]; // 比较函数 int cmp(const void *a, const void *b) { return ((struct Edge *)a)->weight - ((struct Edge *)b)->weight; } // 初始化并查集 void init_union_find(int n) { for (int i = 1; i <= n; i++) { fa[i] = i; } } // 查找根节点 int find_set(int x) { if (fa[x] == x) { return x; } return fa[x] = find_set(fa[x]); } // 合并集合 void merge(int x, int y) { fa[find_set(x)] = find_set(y); } // 克鲁斯卡尔算法 void kruskal(struct Graph *g) { int cnt = 0; // 记录加入的边数 int ans = 0; // 记录最小生成树的权值和 init_union_find(g->n); // 初始化并查集 qsort(g->edges, g->m, sizeof(struct Edge), cmp); // 对边按权值排序 for (int i = 0; i < g->m; i++) { int start = g->edges[i].start; int end = g->edges[i].end; int weight = g->edges[i].weight; if (find_set(start) != find_set(end)) { // 如果不在同一个集合中 merge(start, end); // 合并集合 cnt++; // 边数加一 ans += weight; // 权值和增加 if (cnt == g->n - 1) { // 边数等于顶点数减一,说明已经构成了最小生成树 break; } } } printf("The weight of the minimum spanning tree is: %d\n", ans); } int main() { struct Graph g = {6, 9, {{1, 2, 6}, {1, 3, 1}, {1, 4, 5}, {2, 3, 5}, {2, 5, 3}, {3, 4, 5}, {3, 5, 6}, {3, 6, 4}, {4, 6, 2}}}; kruskal(&g); return 0; } ``` 以上代码实现了克鲁斯卡尔算法,其中包括了并查集的实现。您可以根据需要修改顶点数、边数以及边的具体信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值