最小生成树——Kruskal算法(C语言版)

1,问题描述设G=(V,E)是无向连通带权图,如果G的一个子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树的各边权的总和称为该生成树的耗费,求在G的所有生成树中耗费最小的最小生成树。2,算法思想(1)将代价树中权值非0的所有的边进行小顶堆排序,依次存入到road[]数组中,然后将road[]进行倒置,注意在进行排序时,按照road[i]的权值进行排序,然后记
摘要由CSDN通过智能技术生成


1,问题描述

设G=(V,E)是无向连通带权图,如果G的一个子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树的各边权的总和称为该生成树的耗费,求在G的所有生成树中耗费最小的最小生成树。

2,算法思想

(1)将代价树中权值非0的所有的边进行小顶堆排序,依次存入到road[]数组中,然后将road[]进行倒置,注意在进行排序时,按照road[i]的权值进行排序,然后记录这条边的起始顶点也要相对应。

(2)从最小边开始扫描各边,并检测当前所选边的加入是否会构成回路,如果不会构成回路,则将该边并入到最小生成树中。

(3)不断重复步骤2,直到所有的边都检测完为止。

其中判断当前检测边的加入是否会使原来生成树构成回路的算法思想是:

  (1)采用树的双亲存储结构,即数组v[i]的值表示编号为i的顶点的父结点编号。并将数组v[]初始化为v[i]=i;

  (2)若当前要并入的边起点为a,终点为b,需要判断起点a是否被修改过,即a!=v[a],若已被修改过,就要修改终点v[b]的值,使v[b]=a,即结点b的父结点为a。

  (3)若当前检测的边结点起点为a,终点为b,则判断该边是否能被加入的方法是:分别访问a,b的根结点(a,b的父结点有可能还有父结点),若a,b的根结点相同,则不可以并入,否则可以将该边并入。

取得顶点a根结点的算法实现为:

     //顶点a所在的连通分支号

int GetRoot(int a){

while(a!=v[a]){

   a=v[a];

}

return a;

}

3程序设计

(1)所用数据结构,图的存储结构模块(nodetype.h)

#define maxSize 20

typedef struct{

   int no;

}VertexType;  //结点类型定义                                 

typedef struct{

   int n;     //图的顶点数

   int e;     //图的所有边数

   VertexType vex[maxSize];//顶点信息

   int edges[maxSize][maxSize];//各边的权值

}MGraph;  //图的存储结构                                     

typedef struct{

   int a;//边的起点

   int b;//边的终点

   int w;//边的权值

}Road;    //权值非0的边的存储结构

(2)主模块(main_Kruskal.cpp)

#include

#include

#include"nodetype.h"

#include"initlize.h"

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值