Java 有向带权树-最短路径

理解的还是不够透彻,明天再看看


package com.guge.test.graph;

/**
 * 有向带权树-最短路径
 * Created by Guge on 2017/6/20.
 */
public class GraphPath {
    private final int MAX_SIZE = 20;
    private final int INFINITY = 100000;
    private Vertex[] vertexList;
    private int[][] adjMat;  //邻接矩阵
    private int currentVert;  //当前顶点
    private int nTree;  //最小生成树数量
    private int nVerts;
    private DistPar[] sPath;
    private int startToCurrent;  //起始点到当前顶点的距离


    public GraphPath() {
        vertexList = new Vertex[MAX_SIZE];
        adjMat = new int[MAX_SIZE][MAX_SIZE];
        for (int i = 0; i < MAX_SIZE; i++) {
            for (int j = 0; j < MAX_SIZE; j++) {
                adjMat[i][j] = INFINITY;
            }
        }
        sPath=new DistPar[MAX_SIZE];
        nTree = 0;
        nVerts = 0;
        startToCurrent=0;
    }


    /**
     * 最短路径
     */
    public void path(){
        int startTree=0;
        vertexList[startTree].isInTree=true;
        nTree=1;

        for (int i = 0; i < nVerts; i++) {
            int tempDist=adjMat[startTree][i];
            sPath[i]=new DistPar(tempDist,startTree);
        }

        while (nTree<nVerts){
            int minIndex=getMin();
            int minDist=sPath[minIndex].distance;

            if(minDist==INFINITY){
                System.out.println("Error");
                break;
            }else {
                currentVert=minIndex;
                startToCurrent=sPath[minIndex].distance;
            }

            vertexList[currentVert].isInTree=true;
            nTree++;
            adjust_sPath();
        }
        disPlayPaths();

        nTree=0;
        for (int i = 0; i < nVerts; i++) {
            vertexList[i].isInTree=false;
        }

    }


    /**
     * 找到最小距离
     * @return
     */
    public int getMin(){
        int minDist=INFINITY;
        int minIndex=0;
        for (int i = 0; i < nVerts; i++) {
            if(!vertexList[i].isInTree&&sPath[i].distance<minDist){
                minDist=sPath[i].distance;
                minIndex=i;
            }
        }
        return minIndex;
    }

    /**
     * 更新距离数组
     */
    public void adjust_sPath(){
        int colume=1;
        while (colume<nVerts){
            if(vertexList[colume].isInTree){
                colume++;
                continue;
            }
            int currentToFringe=adjMat[currentVert][colume]; //当前顶点到边缘的距离

            int startToFringe=startToCurrent+currentToFringe;  //起始点到边缘的距离

            int sPathDist=sPath[colume].distance;   //数组存储的距离

            if(startToFringe<sPathDist){  //更新数组
                sPath[colume].parentVert=currentVert;
                sPath[colume].distance=startToFringe;
            }
            colume++;
        }
    }


    public void disPlayPaths(){
        for (int i = 0; i < nVerts; i++) {
            System.out.print(vertexList[i].label+"=");
            if(sPath[i].distance==INFINITY)
                System.out.print("inf");
            else
                System.out.print(sPath[i].distance);
            char parent=vertexList[sPath[i].parentVert].label;
            System.out.print("("+parent+")  ");
        }
        System.out.println();
    }


    public void addVert(char vertex){
        vertexList[nVerts++]=new Vertex(vertex);
    }

    public void addEdge(int start,int end,int weight){
        adjMat[start][end]=weight;
    }

    public void displayVertex(int index){
        System.out.print(vertexList[index].label);
    }

    /**
     * 顶点
     */
    class Vertex {
        public char label;
        public boolean isInTree;

        public Vertex(char label) {
            this.label = label;
            isInTree = false;
        }
    }

    class DistPar {
        public int distance; //距离
        public int parentVert; //上级顶点

        public DistPar(int dist, int parent) {
            distance = dist;
            parentVert = parent;
        }
    }
}

class PathApp{
    public static void main(String[] args) {
        GraphPath graphW=new GraphPath();
        graphW.addVert('A');
        graphW.addVert('B');
        graphW.addVert('C');
        graphW.addVert('D');
        graphW.addVert('E');

        graphW.addEdge(0,1,50);  //AB 50
        graphW.addEdge(0,3,80);  //AD 80
        graphW.addEdge(1,2,60);  //BC 60
        graphW.addEdge(1,3,90);  //BD 90
        graphW.addEdge(2,4,40);  //CE 40
        graphW.addEdge(3,2,20);  //DC 20
        graphW.addEdge(3,4,70);  //DE 70
        graphW.addEdge(4,1,50);  //EB 50

        graphW.path();
        System.out.println();

    }
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值