kruskal算法的Java实现

学过算法的基本都知道,kruskal和prim算法应用最广泛
在学习过程中使用C++语言实现了kruskal
使用List实现kruskal最下生成树的核心算法

kruskal算法的Java实现

import java.util.ArrayList;
import java.util.List;

/**
 * 本类实现最小生成树的克鲁斯卡尔算法
 * Author:Bees
 * Date:2020/1/1
 * statc:finished
 */

/**
 * 示例邻接矩阵
 * 1-A 2-B 3-C 4-D
 *
 *     1  2   3  4
 * 1   0  1   2  3
 * 2   1  0   4  6
 * 3   2  4   0  5
 * 4   3  6   5  0
 *
 * 步骤
 * 1、创建临接矩阵
 * 2、邻接矩阵转顶点数组
 * 3、按照权值排序顶点数组
 * 4、获取最小生成树
 *
 */

public class kruskal {

    /**
     * 顶点类
     */
    class edge{
        int u,v,cost;
        //顶点u,v,权值
    }

    /**
     * 构造
     */
   public kruskal(){

       int cost[][]={{0,1,2,3},
                     {1,0,4,6},
                     {2,4,0,5},
                     {3,6,5,0}};
       edge e[]=Kuruskal(sort(CreatEdge(cost)),cost.length);
   }

    /**
     * 核心算法:构造最小生成树
     * @param e 顶点类数组
     * @param n 顶点数
     * @return 返回最小生成树顶点数组
     */
    public edge[] Kuruskal(edge[] e,int n){
        List<edge> edgeList=new ArrayList();
        for(int i=0;i<e.length;i++){
            edge e_tmp=e[i];
            if(!Sround(e_tmp,edgeList))
                edgeList.add(e_tmp);
            if(edgeList.size()==n-1)//最小生成树完成
                break;
        }
        edge result[]=new edge[n-1];//列表转数组
        for(int i=0;i<n-1;i++)
            result[i]=edgeList.get(i);
       return  result;
    }

    /**
     * 检测是否成环
     * @param e 待加入的顶点
     * @param e_lst  已在树中的顶点列表
     * @return  是否成环
     */
    private boolean Sround(edge e,List<edge>e_lst){
       boolean uu=false,vv=false;
       for(edge i:e_lst) {
            if(i.u==e.u||i.v==e.u)
                uu=true;
            if(i.u==e.v||i.v==e.v)
               vv=true;
       }
       return uu&&vv;
    }

    /**
     * 从邻接矩阵创建顶点数组
     * @param cost 邻接矩阵
     * @return      顶点数组
     */
    public edge[] CreatEdge(int cost[][]){
        if(cost.length!=cost[0].length)
            return null;//输入非法矩阵
        int n=cost.length;
        int e_count_Max=(n*(n-1))/2;
        int p=0;
        for(int i[]:cost)
            for(int j:i)
                if(j==0)
                    p++;
        int e_count=e_count_Max-((n-p)/2);//算出矩阵中有多少条边
        edge e[]=new edge[e_count];
        int ee=0;
        for(int i=0;i<cost.length-1;i++){
            for(int j=i+1;j<cost.length;j++){
                if(cost[i][j]!=0) {
                    edge temp=new edge();
                    temp.u=i+1;
                    temp.v=j+1;
                    temp.cost=cost[i][j];
                    e[ee]=temp;
                    ee++;
                }
            }
        }
        return e;
    }

    /**
     * 本函数功能为根据顶点的权值排序
     * @param e 顶点数组
     * @return  排序后的顶点数组
     */
    private edge[] sort(edge[] e){
        for(int i=0;i<e.length-1;i++){
            for(int j=i+1;j<e.length;j++){
                if(e[i].cost>e[j].cost){
                    edge temp=e[i];
                    e[i]=e[j];
                    e[j]=temp;
                }
            }
        }
        return e;
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值