最短路径——迪杰斯特拉 Dijkstra 算法

Dijkstra算法用于解决单源最短路径问题;是贪婪算法的最好的例子。
在这里插入图片描述
在上述有向图中,要计算从点1到达其余各点的最短路径。其中两点之间的有向箭头表示从起点到终点的距离,例:0~2之间的箭头表示从0到2的距离为30,从2到0是不可达的。
这里我们使用邻接矩阵data[][]来存储点到点之间的距离,data[3][4]表示3~4的路径,-1表示不可达;

{{ 0, -1, 10, -1, 30, 100},
 {-1,  0,  5, -1, -1, -1},
 {-1, -1,  0, 50, -1, -1},
 {-1, -1, -1,  0, -1, 10},
 {-1, -1, -1, 20,  0, 60},
 {-1, -1, -1, -1, -1,  0}}

定义一个dis数组表示各点到起点的最短路径,在初始时,起点到各点的距离默认为无穷大(代码中通过Integer.MAX_VALUE)表示;
定义一个loc表示当前的节点;
Dijkstra算法的思路:
在这里插入图片描述
代码实现

public class Dijkstra {
    public static int[][] data = {
            { 0, -1, 10, -1, 30, 100},
            {-1,  0,  5, -1, -1, -1},
            {-1, -1,  0, 50, -1, -1},
            {-1, -1, -1,  0, -1, 10},
            {-1, -1, -1, 20,  0, 60},
            {-1, -1, -1, -1, -1,  0}
    };

    private static class Distance implements Comparable<Distance> {
        int num;
        int distance = Integer.MAX_VALUE;
        List<Integer> path = new ArrayList<>();
        boolean mark = false;

        public Distance(int num) {
            this.num = num;
        }

        @Override
        public String toString() {
            return "Distance{" +
                    "num=" + num +
                    ", distance=" + distance +
                    ", path=" + path +
                    '}';
        }

        @Override
        public int compareTo(Distance o) {
            if (o == null) {
                return 1;
            }
            return Integer.compare(distance, o.distance);
        }
    }

    private static List<Distance> dis = new ArrayList<>();
    private static PriorityQueue<Distance> queue = new PriorityQueue<>();

    public static void initDis() {
        for (int i = 0; i < 6; i++) {
            dis.add(new Distance(i));
        }

    }

    public static void dijkstra(int startIndex) {
        if (startIndex < 0 || startIndex >= dis.size()) {
            return;
        }
        Distance loc = dis.get(startIndex);
        loc.distance = 0;
        while (loc != null) {
            loc.mark = true;
            loc.path.add(loc.num);
            System.out.println(loc.toString());
            // 更新其他未被标记的点到起点的最短距离
            for (Distance tem: dis) {
                if (tem.mark) {
                    continue;
                }
                // 如果loc到tem可达,且距离小于上一个次判断的距离
                if (data[loc.num][tem.num] != -1 && tem.distance > loc.distance + data[loc.num][tem.num]) {
                    tem.distance = loc.distance + data[loc.num][tem.num];
                    tem.path.clear();
                    tem.path.addAll(loc.path);
                }
                queue.add(tem);
            }
            loc = queue.poll();
            queue.clear();
        }
    }

    public static void main(String[] args) {
        initDis();
        dijkstra(0);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值