寻路算法
图的寻路算法也可以通过深度优先遍历 dfs 实现,寻找图 graph 从起始 s 点到其他点的路径,在上一小节的实现类中添加全局变量 from数组记录路径,from[i] 表示查找的路径上i的上一个节点。
首先构造函数初始化寻路算法的初始条件, from = new int[G.V()] 和 from = new int[G.V()] ,并在循环中设置默认值,visited 数组全部为false,from 数组全部为 -1 值,后面对起始节点进行 dfs 的递归处理。
...
// 构造函数, 寻路算法, 寻找图graph从s点到其他点的路径
public Path ( Graph graph, int s ) {
// 算法初始化
G = graph ;
assert s >= && s < G. V ( ) ;
visited = new boolean [ G. V ( ) ] ;
from = new int [ G. V ( ) ] ;
for ( int i = ; i < G. V ( ) ; i ++ ) {
visited [ i ] = false ;
from [ i ] = - 1 ;
}
this . s = s ;
// 寻路算法
dfs ( s ) ;
}
...
// 构造函数, 寻路算法, 寻找图graph从s点到其他点的路径
public Path ( Graph graph, int s ) {
// 算法初始化
G = graph ;
assert s >= && s < G. V ( ) ;
visited = new boolean [ G. V ( ) ] ;
from = new int [ G. V ( ) ] ;
for ( int i = ; i < G. V ( ) ; i ++ ) {
visited [ i ] = false ;
from [ i ] = - 1 ;
}
this . s = s ;
// 寻路算法
dfs ( s ) ;
}
...
那么判断 s 点到 w 点是否有路径,只要查询 visited 对应数组值即可。
...
boolean hasPath ( int w ) {
assert w >= && w < G. V ( ) ;
return visited [ w ] ;
}
...
boolean hasPath ( int w ) {
assert w >= && w < G. V ( ) ;
return visited [ w ] ;
}
...
获取 s 点到 w 点的具体路径,我们用 path 方法来实现,先判断是否连通,可调用 hasPath 方法,由构造函数可知只需通过 from 数组往上追溯就能找到所有的路径。
...
Vector < Integer > path ( int w ) {
assert hasPath ( w ) ;
Stack < Integer > s = new Stack < Integer > ( ) ;
// 通过from数组逆向查找到从s到w的路径, 存放到栈中
int p = w ;
while ( p != - 1 ) {
s. push ( p ) ;
p = from [ p ] ;
}
// 从栈中依次取出元素, 获得顺序的从s到w的路径
Vector < Integer > res = new Vector < Integer > ( ) ;
while ( ! s. empty ( ) )
res. add ( s. pop ( ) ) ;
return res ;
}
...
Vector < Integer > path ( int w ) {
assert hasPath ( w ) ;
Stack < Integer > s = new Stack < Integer > ( ) ;
// 通过from数组逆向查找到从s到w的路径, 存放到栈中
int p = w ;
while ( p != - 1 ) {
s. push ( p ) ;
p = from [ p ] ;
}
// 从栈中依次取出元素, 获得顺序的从s到w的路径
Vector < Integer > res = new Vector < Integer > ( ) ;
while ( ! s. empty ( ) )
res. add ( s. pop ( ) ) ;
return res ;
}
...
Java 实例代码
源码包下载: Download
src/yssmx/graph/Path.java 文件代码:
package
yssmx.graph
;
import yssmx.graph.read.Graph ;
import java.util.Stack ;
import java.util.Vector ;
/**
* 寻路
*/
public class Path {
// 图的引用
private Graph G ;
// 起始点
private int s ;
// 记录dfs的过程中节点是否被访问
private boolean [ ] visited ;
// 记录路径, from[i]表示查找的路径上i的上一个节点
private int [ ] from ;
// 图的深度优先遍历
private void dfs ( int v ) {
visited [ v ] = true ;
for ( int i : G. adj ( v ) )
if ( ! visited [ i ] ) {
from [ i ] = v ;
dfs ( i ) ;
}
}
// 构造函数, 寻路算法, 寻找图graph从s点到其他点的路径
public Path ( Graph graph, int s ) {
// 算法初始化
G = graph ;
assert s >= && s < G. V ( ) ;
visited = new boolean [ G. V ( ) ] ;
from = new int [ G. V ( ) ] ;
for ( int i = ; i < G. V ( ) ; i ++ ) {
visited [ i ] = false ;
from [ i ] = - 1 ;
}
this . s = s ;
// 寻路算法
dfs ( s ) ;
}
// 查询从s点到w点是否有路径
boolean hasPath ( int w ) {
assert w >= && w < G. V ( ) ;
return visited [ w ] ;
}
// 查询从s点到w点的路径, 存放在vec中
Vector < Integer > path ( int w ) {
assert hasPath ( w ) ;
Stack < Integer > s = new Stack < Integer > ( ) ;
// 通过from数组逆向查找到从s到w的路径, 存放到栈中
int p = w ;
while ( p != - 1 ) {
s. push ( p ) ;
p = from [ p ] ;
}
// 从栈中依次取出元素, 获得顺序的从s到w的路径
Vector < Integer > res = new Vector < Integer > ( ) ;
while ( ! s. empty ( ) )
res. add ( s. pop ( ) ) ;
return res ;
}
// 打印出从s点到w点的路径
void showPath ( int w ) {
assert hasPath ( w ) ;
Vector < Integer > vec = path ( w ) ;
for ( int i = ; i < vec. size ( ) ; i ++ ) {
System . out . print ( vec. elementAt ( i ) ) ;
if ( i == vec. size ( ) - 1 )
System . out . println ( ) ;
else
System . out . print ( " -> " ) ;
}
}
}
import yssmx.graph.read.Graph ;
import java.util.Stack ;
import java.util.Vector ;
/**
* 寻路
*/
public class Path {
// 图的引用
private Graph G ;
// 起始点
private int s ;
// 记录dfs的过程中节点是否被访问
private boolean [ ] visited ;
// 记录路径, from[i]表示查找的路径上i的上一个节点
private int [ ] from ;
// 图的深度优先遍历
private void dfs ( int v ) {
visited [ v ] = true ;
for ( int i : G. adj ( v ) )
if ( ! visited [ i ] ) {
from [ i ] = v ;
dfs ( i ) ;
}
}
// 构造函数, 寻路算法, 寻找图graph从s点到其他点的路径
public Path ( Graph graph, int s ) {
// 算法初始化
G = graph ;
assert s >= && s < G. V ( ) ;
visited = new boolean [ G. V ( ) ] ;
from = new int [ G. V ( ) ] ;
for ( int i = ; i < G. V ( ) ; i ++ ) {
visited [ i ] = false ;
from [ i ] = - 1 ;
}
this . s = s ;
// 寻路算法
dfs ( s ) ;
}
// 查询从s点到w点是否有路径
boolean hasPath ( int w ) {
assert w >= && w < G. V ( ) ;
return visited [ w ] ;
}
// 查询从s点到w点的路径, 存放在vec中
Vector < Integer > path ( int w ) {
assert hasPath ( w ) ;
Stack < Integer > s = new Stack < Integer > ( ) ;
// 通过from数组逆向查找到从s到w的路径, 存放到栈中
int p = w ;
while ( p != - 1 ) {
s. push ( p ) ;
p = from [ p ] ;
}
// 从栈中依次取出元素, 获得顺序的从s到w的路径
Vector < Integer > res = new Vector < Integer > ( ) ;
while ( ! s. empty ( ) )
res. add ( s. pop ( ) ) ;
return res ;
}
// 打印出从s点到w点的路径
void showPath ( int w ) {
assert hasPath ( w ) ;
Vector < Integer > vec = path ( w ) ;
for ( int i = ; i < vec. size ( ) ; i ++ ) {
System . out . print ( vec. elementAt ( i ) ) ;
if ( i == vec. size ( ) - 1 )
System . out . println ( ) ;
else
System . out . print ( " -> " ) ;
}
}
}