SW练习_求最短距离_迪杰斯特拉

本文介绍了迪杰斯特拉算法的概要,即从没访问的点中找到离起点最近的点并更新其相邻未访问点的距离。文章提出疑问,在某些情况下,如某个顶点与其他点不连接时,算法如何继续执行,并讨论了如何更新路径长度。

算法概要:从没有访问的点里,找到距离起点最近的点,然后更新该点到其相邻且未访问点的距离

1.找出距离最小的点s1 这块我其实有个疑问,如果be这个顶点和别的点都不连接,那么这块计算不下去了?

2.根据s1到它连接的每一个e1,如果 (开始节点->s1)+(s1->e1)<(开始节点->e1) 那么开始节点->e1需要更新一下

package info.frady.algo;

/**
 meng3.wei 2020.04.25
 //参考 https://www.jianshu.com/p/ff6db00ad866
 从0出发到0的最短距离为:0
 0-->0
 从0出发到1的最短距离为:3
 0-->3-->1
 从0出发到2的最短距离为:3
 0-->3-->2
 从0出发到3的最短距离为:2
 0-->3
 从0出发到4的最短距离为:6
 0-->3-->2-->4
 */
public class 迪杰斯特拉 {
    public static final int M = 1000000; // 代表正无穷
    public static int n;//顶点的个数
    public static int[] shortPathLen ; // 保存start到其他各点的最短路径
    public static boolean [] visited;
    public static int[] pid;

    public static void main(String[] args) {
        // 二维数组每一行分别是 A、B、C、D、E 各点到其余点的距离,
        // A -> A 距离为0, 常量M 为正无穷
        int[][] weight1 = {
                {0,4,M,2,M},
                {4,0,4,1,M},
                {M,4,0,1,3},
                {2,1,1,0,7},
                {M,M,3,7,0}
        };
        n=weight1.length;
        pid=new int[n];
        visited=new boolean[n];
        shortPathLen=new int[n];
        int be=0;

        proceeDS(weight1,be);

        for (int i = 0; i < n; i++) {
            System.out.println("从" + 0 + "出发到" + i + "的最短距离为:" + shortPathLen[i]);
            int p=pid[i];
            StringBuffer sb=new StringBuffer();
            sb.append(i);
            while(p!=be){
                sb.append(">--"+p);
                p=pid[p];
            }
            sb.append(">--"+be);
            System.out.println(sb.reverse());
        }

    }
    public static void proceeDS(int[][] weight1,int be){//be代表起点
        pid[be]=be;
        visited[be]=true;
        shortPathLen[be]=0;

        for (int i = 1; i < n; i++) {
            int minLen=Integer.MAX_VALUE;
            int s1=0;
            for (int end = 0; end <n ; end++) {//1.找出距离最小的点s1    这块我其实有个疑问,如果be这个顶点和别的点都不连接,那么这块计算不下去了?
                if(!visited[end]  && weight1[be][end]<minLen ){
                    s1=end;
                    minLen=weight1[be][end];
                }
            }
            shortPathLen[s1]=minLen;
            visited[s1]=true;

            for (int e1 = 0; e1<n ; e1++) {//2.根据s1到它连接的每一个e1,如果 (开始节点->s1)+(s1->e1)<(开始节点->e1) 那么开始节点->e1需要更新一下
                if( !visited[e1] && (weight1[be][s1]+ weight1[s1][e1] <weight1[be][e1]) ){

                    weight1[be][e1]=weight1[be][s1]+ weight1[s1][e1];
                    pid[e1]=s1;

                }
            }
        }

    }


}

 

迪杰斯特拉算法(Dijkstra)是一种贪心算法,用于解决最短路径问题。它可以处理有权有向图或无向图,但不允许有负权边(权重必须为非负数)。 算法思路: 1. 从起点开始,初始化所有节点的距离为无穷大,起点距离为0; 2. 将起点加入“已访问”集合; 3. 对于起点的所有邻居节点,更新它们的距离(如果通过当前节点到达邻居节点的距离小于邻居节点原有的距离,则更新邻居节点的距离); 4. 从未访问集合中选择距离起点最近的节点,加入“已访问”集合; 5. 重复步骤3和4,直到所有节点都被加入“已访问”集合或者没有与起点相连的节点。 算法实现: Dijkstra算法的实现通常使用优先队列(PriorityQueue)来维护未访问集合中距离起点最近的节点。具体实现步骤如下: 1. 创建一个空的优先队列Q,将起点加入Q中,并设置起点到自身的距离为0; 2. 创建一个数组dist[],用于保存起点到各个节点的距离,初始化为无穷大; 3. 创建一个数组visited[],用于标记节点是否被访问过,初始化为false; 4. 将dist[起点]的值设置为0; 5. 当Q不为空时,重复以下步骤: a. 从Q中取出距离起点最近的节点u; b. 如果节点u已经被访问过,则跳过此次循环; c. 将节点u标记为已访问; d. 对于节点u的每个邻居节点v,如果节点v未被访问过并且通过节点u到达节点v的距离小于dist[v],则更新dist[v]的值; e. 将节点v加入Q中。 6. 最终,dist数组中保存的就是起点到各个节点的最短距离。 Dijkstra算法的时间复杂度为O(ElogV),其中E为边数,V为节点数。这是因为算法需要对每个节点的所有邻居节点进行遍历,而优先队列的插入和删除操作的时间复杂度为O(logV)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值