最小生成树-普里姆算法\克鲁斯卡尔算法

/**
 * 最小生成树:找寻图中连接所有顶点的最短距离的路径
 * 普里姆算法(prim)和克鲁斯卡尔算法(kruskal)
 *       v0    v1    v2    v3    v4    v5    v6    v7   v8
 * v0    0     10    #     #     #     11    #     #    #
 * v1    10    0     18    #     #     #     16    #    12
 * v2    #     #     0     22    #     #     #     #    8
 * v3    #     #     22    0     20    #     #     16   21
 * v4    #     #     #     20    0     26    #     7    #
 * v5    11    #     #     #     26    0     17    #    #
 * v6    #     16    #     #     #     17    0     19   #
 * v7    #     #     #     16    7     #     19    0    #
 * v8    #     12    8     21    #     #     #     #    0
 * #:代表2点之间无连接
 */
public class MixTree {
    public String [] topPoint={"0","1","2","3","4","5","6","7","8"};
    public int length=9;
    //65535=没有边
    public int[][] sides={
            {0, 10,65535, 65535, 65535, 11,65535, 65535,65535},
            {10,0, 18,65535, 65535, 65535, 16,65535,12},
            {65535, 65535, 0, 22,65535, 65535, 65535, 65535,8},
            {65535, 65535, 22,0, 20,65535, 65535, 16,21},
            {65535, 65535, 65535, 20,0, 26,65535, 7,65535},
            {11,65535, 65535, 65535, 26,0, 17,65535,65535},
            {65535, 16,65535, 65535, 65535, 17,0, 19,65535},
            {65535, 65535, 65535, 16,7, 65535, 19,0,65535},
            {65535, 12,8, 21,65535, 65535, 65535, 65535,0}
    };

    public static void main(String[] args) {
        MixTree mixTree=new MixTree();
        mixTree.prim(new MGraph());
    }
    //适用用边数多的图
    private void prim(MGraph g){
        int maxLength=9,infinity=65535;
        int min,j,k;
        //相关顶点的下标
        int adjvex[]=new int[maxLength];
        //权值数组
        int lowCost[]=new int[maxLength];
        //初始化,此下标的顶点假如生成树
        lowCost[0]=0;
        adjvex[0]=0;
        for (int i = 1; i < g.length; i++) {
            //将v0顶点与之有边的权值存入数组
            lowCost[i]=g.sides[0][i];
            //初始化都为v0的下标
            adjvex[i]=0;
        }
        //此时:lowCost={0     10    #     #     #     11    #     #    #},#=65535

        //整个循环,构造最小生成树的过程
        for (int i = 1; i < g.length; i++) {
            min=infinity;
            j=1;k=0;
//            循环全部顶点,找到当前lowCost数组中的最小值,
            while (j<g.length){
                if(lowCost[j]!=0 && lowCost[j] < min){
                    min=lowCost[j];
                    k=j;
                }
                j++;
            }
            //i=1 打印 (0,1)
            System.out.println("("+adjvex[k]+","+k+")");
            //将当前顶点的权值设置为0,表示此顶点已经完成任务
            lowCost[k]=0;
            for (j = 1; j < g.length; j++) {
                //将k行的数据中小于lowCost数组数据,替换相同下标的lowCost数组 (关键)
                //此时lowCost={0     0    #     #     #     11    #     #    #};
                //k=1所以,g.sides[1][j]={10    0     18    #     #     #     16    #    12}
                if(lowCost[j]!=0 && g.sides[k][j] < lowCost[j]){
                    //将较小权值存入lowCost
                    lowCost[j]=g.sides[k][j];
                   //下标为k的顶点存入adjvex
                    adjvex[j]=k;
                }
            }//这时lowCost={0     0    18     #     #     11    16     #    12},adjvex={0,0,1,0,0,0,1,0,1},
            // adjvex[2]=1表示lowCost[2]的权值是替换的,
        }
    }
}
//克鲁斯卡尔算法,检查是否有回路
    private void kruskal(EdgeGraph g){
        int n,m;
        EdgeNode edges[]=g.edges;
        int parent[]=new int[9];
        for (int i = 0; i < g.lengthTop; i++) {
            parent[i]=0;
        }
        for (int i = 0; i < g.lengthEdge; i++) {
            n=find(parent,edges[i].getBegin());
            m=find(parent,edges[i].getEnd());
            //不等,则说明此边没有与现有生成树形成环路
            if(n!=m){
                //将此边的结尾顶点放入下标为起点的parent中
                //表示此顶点已经在生成树集合中
                parent[n]=m;
                System.out.printf("(%d,%d) %d",edges[i].getBegin(),edges[i].getEnd(),edges[i].getWeight());
                System.out.println();
            }
        }

    }
/*
    {1,5,8,7,7,8,0,0,6} new EdgeNode(5,6,17), 1,2,18
    i=7 n=5,8,6  m=6
 */
    //查找连线顶点的尾部下标,
    private int find(int parent[],int f){
        while (parent[f]>0){
            f=parent[f];
        }
        return f;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值