prim和kruskal求最小生成树

package com.haitao.prim;

import java.util.Arrays;

public class PrimTree {
    public static void main(String[] args) {
        char[] data = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int[][] weight = new int[][]{
                {10000, 5, 7, 10000, 10000, 10000, 2},
                {5, 10000, 10000, 9, 10000, 10000, 3},
                {7, 10000, 10000, 10000, 8, 10000, 10000},
                {10000, 9, 10000, 10000, 10000, 4, 10000},
                {10000, 10000, 8, 10000, 10000, 5, 4},
                {10000, 10000, 10000, 4, 5, 10000, 6},
                {2, 3, 10000, 10000, 4, 6, 10000}
        };
        MGraph mGraph = new MGraph(data.length);
        minPrim minPrim = new minPrim();
        minPrim.createGraph(mGraph, data.length, data, weight);
        minPrim.showGraph(mGraph);
        minPrim.createMinTree(mGraph,0);
    }
}

class minPrim {
    public void createGraph(MGraph mGraph, int vxters, char[] data, int[][] weight) {
        for (int i = 0; i < vxters; i++) {
            mGraph.data[i] = data[i];
            for (int j = 0; j < vxters; j++) {
                mGraph.weight[i][j] = weight[i][j];
            }
        }
    }

    public void showGraph(MGraph mGraph) {
        for (int[] arr : mGraph.weight) {
            System.out.println(Arrays.toString(arr));
        }
    }

    public void createMinTree(MGraph mGraph,int start) {
        int[] isVisited = new int[mGraph.vxters];
        isVisited[start] = 1;
        int h1 = -1;
        int h2 = -1;
        for (int i = 1; i < mGraph.vxters; i++) {
            int minValue = 10000;
            for (int j = 0; j < mGraph.vxters; j++) {
                for (int k = 0; k < mGraph.vxters; k++) {
                    if (isVisited[j] == 1 && isVisited[k] == 0 && mGraph.weight[j][k] < minValue) {
                        minValue = mGraph.weight[j][k];
                        h1 = j;
                        h2 = k;
                    }
                }
            }
            isVisited[h2] = 1;
            System.out.println(mGraph.data[h1]+"->"+mGraph.data[h2]+"的路径是"+mGraph.weight[h1][h2]);
        }
    }
}

class MGraph {
    int vxters;
    char[] data;
    int[][] weight;

    public MGraph(int vxters) {
        this.vxters = vxters;
        data = new char[vxters];
        weight = new int[vxters][vxters];
    }
}

package com.haitao.kruskal;

/**
 * @Describe 克鲁斯卡尔算法
 * @Author haitao
 * @Date 2021/11/30 23:00
 * @Version 1.0
 */
public class KruskalCase {
    //顶点
    private char[] vertexes;
    //边
    private int[][] matrix;

    private int edgeNum;

    private final static int MAX_VALUE = Integer.MAX_VALUE;

    public static void main(String[] args) {
        char[] vertexes = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int[][] matrix = {{0, 12, MAX_VALUE, MAX_VALUE, MAX_VALUE, 16, 14},
                {12, 0, 10, MAX_VALUE, MAX_VALUE, 7, MAX_VALUE},
                {MAX_VALUE, 10, 0, 3, 5, 6, MAX_VALUE},
                {MAX_VALUE, MAX_VALUE, 3, 0, 4, MAX_VALUE,MAX_VALUE},
                {MAX_VALUE, MAX_VALUE, 5, 4, 0, 2, 8},
                {16, 7, 6, MAX_VALUE, 2, 0, 9},
                {14, MAX_VALUE, MAX_VALUE, MAX_VALUE, 8, 9, 0}};
        KruskalCase kruskalCase = new KruskalCase(vertexes, matrix);

        kruskalCase.kruskal();
    }

    public KruskalCase(char[] vertexes, int[][] matrix) {
        int len = vertexes.length;
        this.vertexes = new char[len];
        for (int i = 0; i < vertexes.length; i++) {
            this.vertexes[i] = vertexes[i];
        }

        this.matrix = new int[len][len];
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                this.matrix[i][j] = matrix[i][j];
            }
        }

        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j < len; j++) {
                if (this.matrix[i][j] != MAX_VALUE) {
                    edgeNum++;
                }
            }
        }
    }

    private void kruskal() {
        //表示最后结果数组的索引
        int index = 0;
        //用于保存最小生成树中每个每个顶点在最小生成树中的终点
        int[] ends = new int[edgeNum];
        //创建结果数组,保存最后的最小生成树
        EData[] results = new EData[edgeNum];

        //获取图中所有的边
        EData[] eData = getEData();
        sortEDatas(eData);

        //遍历eData数组,将边添加到最小生成树中,判断准备加入的边是否形成了回路
        //如果没有,则加入到results中,负责不能加入
        for (int i = 0; i < edgeNum; i++) {
            int firstPosition = getPosition(eData[i].start);
            int firstEnd = getEnd(ends, firstPosition);
            int secondPosition = getPosition(eData[i].end);
            int secondEnd = getEnd(ends, secondPosition);
            if (firstEnd != secondEnd) {
                ends[firstEnd] = secondEnd;
                results[index++] = eData[i];
            }
        }
    }

    private void sortEDatas(EData[] eData) {
        for (int i = 0; i < eData.length - 1; i++) {
            for (int j = 0; j < eData.length - 1 - i; j++) {
                if (eData[j].weight > eData[j + 1].weight) {
                    EData temp = eData[j];
                    eData[j] = eData[j + 1];
                    eData[j + 1] = temp;
                }
            }
        }
    }

    private int getPosition(char ch) {
        for (int i = 0; i < vertexes.length; i++) {
            if (vertexes[i] == ch) {
                return i;
            }
        }
        return -1;
    }

    private EData[] getEData() {
        int index = 0;
        EData[] eData = new EData[edgeNum];
        for (int i = 0; i < vertexes.length; i++) {
            for (int j = i + 1; j < vertexes.length; j++) {
                if (matrix[i][j] != MAX_VALUE) {
                    eData[index++] = new EData(vertexes[i], vertexes[j], matrix[i][j]);
                }
            }
        }
        return eData;
    }

    private int getEnd(int[] ends, int index) {
        while (ends[index] != 0) {
            index = ends[index];
        }
        return index;
    }
}

class EData{
    char start;
    char end;
    int weight;

    public EData(char start, char end, int weight) {
        this.start = start;
        this.end = end;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "EData = [start = " + start + ",end = " + end + ",weight = " + weight + "]";
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值