源于尚硅谷数据结构与算法 对应的弗洛伊德部分
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]+"->");
}
}
节点和顶点字符