图的应用-最短路径(JAVA实现)

Djkstra算法-用于求解单源最短路径问题

设有向图如下,求解V0到其余节点的最短距离

流程:

1)记录V0节点到其余节点的路径与距离,初始时均为直达路径
2)选取集合中的最短路径,路径的另一端点为X
3)若V0经由X到其他节点存在一条更短的路径,则用新路径替代
4)如此循环,直到获得V0到其余节点的最短路径为止

  1. 申请一个节点集合,只包含V0顶点
  2. 若有N个节点,则希望N-1轮后,所有节点归入集合,图中有7个节点,则6轮后所有节点归入集合
  3. 申请一个距离集合,用于存储V0到其余节点的最终距离,初始时为邻接矩阵中V0到其余节点的直达距离{-1,13, 8,-1,30,-1,32}
  4. 第一轮找出从V0出发,取距离集合中的最小距离,将弧另一端节点X加入节点集合
  5. 第二轮找出从V0出发,将经X到其余节点的距离与原距离集合对比,若更小则替换原距离;选出除了节点已在节点集合内的最小弧,将另一端节点加入节点集合
  6. 依次类推,直到节点集合满为止
/**
     * Djkstra算法,用于求解单源最短路径问题
     */
    public static class Djkstra{
        public static void main(String[] args) {
            int[][] matrix = {
                    {-1,13, 8,-1,30,-1,32},
                    {-1,-1,-1,-1,-1, 9, 7},
                    {-1,-1,-1, 5,-1,-1,-1},
                    {-1,-1,-1,-1, 6,-1,-1},
                    {-1,-1,-1,-1,-1, 2,-1},
                    {-1,-1,-1,-1,-1,-1,17},
                    {-1,-1,-1,-1,-1,-1,-1}
            };

            List<Integer> vectors = new ArrayList<>(); //用于存放已归入节点
            vectors.add(0);//初始化,初始只有V0节点

            int[] finalDis = new int[7]; //用于存放V0到其余节点的最终距离
            finalDis = matrix[0];//初始化,初始时最终距离 = 邻接矩阵中V0到其余节点的直达距离

            while (vectors.size()!=7){
                int minVector = getMinVector(finalDis,vectors); //将距离最短的节点归入节点集合

                int minDis = finalDis[minVector]; //到距离最短的节点minVector的距离

                //若经由minVector到其他节点产生了一条更短的路径,则用这条路径替换finalDis中V0到该节点的距离
                for (int i=0;i<7;i++){
                    if (vectors.contains(Integer.valueOf(i))){ continue; } //该节点已经在节点集合中,非其他节点,跳过
                    if (matrix[minVector][i] == -1) { continue; } //经中转节点到该节点无路径,跳过
                    if (matrix[minVector][i] + minDis < finalDis[i] || finalDis[i] == -1) {
                        finalDis[i]  = matrix[minVector][i] + minDis;
                    }
                }

                print(finalDis,vectors); //打印本轮V0到其他节点的最终距离
            }
        }

        public static void print(int[] finalDis,List<Integer> vectors){
            System.out.print("本轮V0到其他节点的最终距离为:");
            for (int finalDi : finalDis) {
                System.out.print(finalDi+",");
            }
            System.out.println();
            System.out.print("节点集合中的节点为:");
            for (Integer vector : vectors) {
                System.out.print(vector+",");
            }
            System.out.println();
        }

        private static int getMinVector(int[] finalDis, List<Integer> vectors) {
            int min = Integer.MAX_VALUE;
            int minVector = -1;
            for (int i = 0;i<finalDis.length;i++){
                if (finalDis[i] != -1 && finalDis[i] < min && !vectors.contains(Integer.valueOf(i))){
                    min = finalDis[i];
                    minVector = i;
                }
            }
            vectors.add(minVector);
            return minVector;
        }
    }

知识点:

  1. 时间复杂度为O(|v|2),因为从代码结构可以看书,这是一个嵌套循环
  2. 如果弧带有负数权值,则Djkstra算法不适用

Floyd算法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值