克鲁斯卡尔算法(最小生成树)

本文介绍了一种使用克鲁斯卡尔算法求解最小生成树的问题,并通过实例展示了如何创建图的边集合并对其进行排序,进而实现最小生成树的构建过程。该算法适用于加权图,并能有效地找到连接所有顶点且权重之和最小的子图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 *
 *
 * */
public class GraphKruskal {
    /**
     * 首先的先将路径排序最从到大
     * 然后算法筛选
     * */
    private Edge[] edges; // 边的集合

    private int edgeSize; // 边的总数

    public GraphKruskal(int edgeSize){
        this.edgeSize = edgeSize;
        edges = new Edge[edgeSize];
    }

    /**
     * 图的创建
     *已经按照权重排序过了
     * */
    public void createEdgeArray(){
        Edge edge0 = new Edge(4,7,7);
        Edge edge1 = new Edge(2,8,8);
        Edge edge2 = new Edge(0,1,10);
        Edge edge3 = new Edge(0,5,11);
        Edge edge4 = new Edge(1,8,12);
        Edge edge5 = new Edge(3,7,16);
        Edge edge6 = new Edge(1,6,16);
        Edge edge7 = new Edge(5,6,17);
        Edge edge8 = new Edge(1,2,18);
        Edge edge9 = new Edge(6,7,19);
        Edge edge10 = new Edge(3,4,20);
        Edge edge11 = new Edge(3,8,21);
        Edge edge12 = new Edge(2,3,22);
        Edge edge13 = new Edge(3,6,24);
        Edge edge14 = new Edge(4,5,26);

        edges[0] =edge0;
        edges[1] =edge1;
        edges[2] =edge2;
        edges[3] =edge3;
        edges[4] =edge4;
        edges[5] =edge5;
        edges[6] =edge6;
        edges[7] =edge7;
        edges[8] =edge8;
        edges[9] =edge9;
        edges[10] =edge10;
        edges[11] =edge11;
        edges[12] =edge12;
        edges[13] =edge13;
        edges[14] =edge14;

    }

    public void miniSpanTreeKruskal(){

        int m , n ,sum = 0;
        // 神奇数组,下标为起点,值为终点
        int[] parent = new int[edgeSize];

        for (int i = 0;i< edgeSize ;i++){
            parent[i] = 0;
        }

        for (int i=0;i<edgeSize;i++){
            // 如果从起点走和从终点走值相同,则为环路
            n = find(parent,edges[i].begin);
            m = find(parent,edges[i].end);
            if (n!=m){
                parent[n] = m; // 否则就选择这条边 下标为起点,值为终点
                System.out.println("起始顶点:"+edges[i].begin+"-->"+"结束顶点"+edges[i].end+"===权值"+edges[i].weight);
                sum += edges[i].weight;
            }


        }
        System.out.println(sum);
    }

    /**
     * 将神奇数组进行查询获取非回环的值
     * */

    public int find(int[] parent,int f){

        while (parent[f] > 0){
            f = parent[f];
        }
        return f;
    }



    // 边的结构
    class Edge{
        private int begin;  //起始顶点
        private int end;   //终点顶点
        private int weight; // 边的权重

        public Edge(int begin,int end ,int weight) {
            this.begin = begin;
            this.end = end;
            this.weight = weight;
        }

        public int getWeight() {
            return weight;
        }

        public void setWeight(int weight) {
            this.weight = weight;
        }

        public int getEnd() {

            return end;
        }

        public void setEnd(int end) {
            this.end = end;
        }

        public int getBegin() {

            return begin;
        }

        public void setBegin(int begin) {
            this.begin = begin;
        }
    }


    public static void main(String[] args) {
        GraphKruskal graphKruskal = new GraphKruskal(15);
        graphKruskal.createEdgeArray();
        graphKruskal.miniSpanTreeKruskal();
        /*结果:
        起始顶点:4-->结束顶点7===权值7
        起始顶点:2-->结束顶点8===权值8
        起始顶点:0-->结束顶点1===权值10
        起始顶点:0-->结束顶点5===权值11
        起始顶点:1-->结束顶点8===权值12
        起始顶点:3-->结束顶点7===权值16
        起始顶点:1-->结束顶点6===权值16
        起始顶点:6-->结束顶点7===权值19
        99*/


    }




}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值