弗洛伊德算法注意项 floyd

源于尚硅谷数据结构与算法 对应的弗洛伊德部分

1.为什么视频中用在判断完之后的赋值是 pre[i][j]=pre[i][k]+pre[k][j] 而不是直接pre[i][j]=k呢?

原因: 因为如果直接赋值k表示 i->k->j   

其中有3种情况    保证最小路径的前提

1.i可以直接到达k,同时也可以直接到达j  

也就是 i->k->j 是最终路径  如果过程是这样的 就可以直接等号右边赋值给k  但很明显情况有3种而不是只有第1这种

2.i在通过一些路径之后到达k就直接到达j 

比如:i->z->k->j   这种情况是i通过一个点z或者通过很多个点才到达k, 这种也是可以的 记录了最后一次的这个前驱节点k    可以直接赋值给k   到时候pre[k][j]仍然是k k开始经过k的前驱节点 即本身到达j

3.i在通过一些路径之后到达k  同时,k还要经过一些路径之后才到达j 

但是,第三种情况就不行了

i->k->z->j  ,k先要去到z 然后才能取到j  如果pre[i][j]=k 那就说明i虽然是经过了k到达了j 然后其实途中最后的一个前驱节点不知道谁了,

有人可能会奇怪只记录最后一个前驱 那中间的k不记录那到时候怎么查路径呢,

其实在判断最小路径的时候已经将i->z的前驱节点记录了,也就是说

如果从i到j的最后记录是pre[i][j]=z;  得出i->z->j  

但这不是最终路径 最终路径需要不断遍历递归得到

就是查i到j的pre[i][j]是否等于i 如果是i就证明i直接到j,如果不是就需要找到j的最后前驱 如图中z

i->z->j  然后再对i->z和z->j这两段进行递归遍历  实际上的效果就是下面2的代码

写的可能有点逻辑不通顺 看看代码就知道了   如果有错误可以评论区留言一下 毕竟水平不是很够

2.显示具体路径

用递归比较容易实现

public void getRoad(int src, int dest, char[] vertex) {
        System.out.print("路线为: ");
        getRoadRecur(src,dest,vertex);
        System.out.println(vertex[dest]);

    }

        /** 递归版
         * @param src
         * @param dest
         * @param vertex
         */
    public void getRoadRecur(int src, int dest, char[] vertex) {
        if(pre[src][dest]!=src){//左
            int mid=pre[src][dest];
            getRoadRecur(src,mid,vertex);
            getRoadRecur(mid,dest,vertex);
        }else {
            System.out.print(vertex[src]+"->");
        }
    }

节点和顶点字符

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值