Java 深度优先/广度优先算法打印所有节点;如何使其仅打印路径中的节点?
我有一个如下形式的邻接矩阵Java 深度优先/广度优先算法打印所有节点;如何使其仅打印路径中的节点?,java,algorithm,nodes,depth-first-search,adjacency-matrix,Java,Algorithm,Nodes,Depth First Search,Adjacency Matrix,我有一个如下形式的邻接矩阵adj: 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 这是规则为adj(x,y)=1的迷宫的邻接矩阵,如果: x!=y x与y相邻 x或y都不是迷宫中的墙 迷宫如下(旁边是元
adj
:
0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0
1 0 0 0 1 0 1 0 0
0 0 0 1 0 1 0 0 0
0 0 1 0 1 0 0 0 1
0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0
这是规则为adj(x,y)=1的迷宫的邻接矩阵,如果:
S
到E
要遍历的节点,但它会显示不必要的节点
public static void main(String [] args){
int[][] adj = //the adjacency matrix
boolean[] visited = new boolean[adj.length];
int n = adj.length;
int m = 1; //starting position
int o = 3; //ending position
DFS(adjMatrix, visited, n, m, o);
}
public static void DFS(int[][] adj, boolean[] visited, int n, int i, int o){
System.out.print(" " + (i+1));
visited[i]= true;
if (i+1 != o) {
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
DFS(adj, visited, n, j, o);
}
}
}
}
public static void BFS(int[][] adj, boolean[] visited, int n, int i, int o){
queue Q = new queue;
visited[i]= true;
Q.enqueue(i);
while (!Q.isEmpty()) {
//...
}
}
publicstaticvoidmain(字符串[]args){
int[][]adj=//邻接矩阵
boolean[]访问=新的boolean[adj.length];
int n=调整长度;
int m=1;//起始位置
int o=3;//结束位置
DFS(调整矩阵、访问、n、m、o);
}
公共静态无效DFS(int[][]adj,boolean[]invested,int n,int i,int o){
系统输出打印(“+(i+1));
访问[我]=真实;
如果(i+1!=o){
对于(int j=0;j请尝试使用以下代码:
public static boolean DFS(int[][] adj, boolean[] visited, int n, int i, int o){
visited[i]= true;
boolean good = false;
if (i+1 != o) {
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
good |= DFS(adj, visited, n, j, o);
}
}
} else {
good = true;
}
if (good) System.out.print(" " + (i+1));
return good;
}
publicstaticbooleandfs(int[][]adj,boolean[]invested,int n,int i,int o){
访问[我]=真实;
布尔好=假;
如果(i+1!=o){
对于(int j=0;j当您最终到达目的地时,方法堆栈将具有路径
ArrayList<Integer> list = new ArrayList<>(); // this will have your path.
public static boolean DFS(int[][] adj, boolean[] visited, int n, int i, int o){
if(i==o){
list.add(o);
//System.out.println(i);
return true;
}
visited[i]= true;
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
if(DFS(adj, visited, n, j, o)){
list.add(0,j);
//System.out.println(j);
return true;
}
}
}
return false;
}
ArrayList list=new ArrayList();//这将有您的路径。
公共静态布尔DFS(int[][]adj,boolean[]已访问,int n,int i,int o){
如果(i==o){
列表。添加(o);
//系统输出打印LN(i);
返回true;
}
访问[我]=真实;
对于(int j=0;j,除了DFS算法所需的修复外,代码还存在一些主要问题:
- 你的开始和结束是错误的:它应该减少1(因为
指数(以0为基础)
- 你的邻接矩阵是错误的(它的大小是
10X9
-它应该是一个平方矩阵)(编辑修复它)
- 您的解决方案应该只打印路径中的元素。一种方法是返回
列表
(而不是void
,它填充当前路径中的所有节点。如果到达目标,请创建列表,否则-返回null
。仅当递归调用返回非null
的内容时才附加元素
还要注意,它按正确的顺序(而不是相反的顺序)打印节点
作为旁注,虽然此解决方案是完整的(如果存在,将始终找到一个解决方案),但它不是最优的-它可能返回比最短的解决方案更长的解决方案
如果您想找到从源到目标的最短路径,请考虑切换到
添加一个签入DFS函数,当您到达您的期望位置时(即O)。从DFS返回。请注意,如果您想找到最短路径,BFS会更好。@riista想象一个100x100的完全空的地图,从左上角开始,从中间结束。BFS可以决定“螺旋进入”,绘制所有内容;或者在最佳情况下绘制地图的一半;在任何一种情况下,返回的路径都将是长且多风的。宽度优先仅绘制地图的一半,并返回最佳路径。@riista DPS立即尽可能深入,因此最有可能(在较大的图形中更明显)如果它找到一条路径,它将不是最短的。BFS从“根”开始逐层展开,因此,如果它找到一条路径,它可能是最短的。@Carcigenicate maybly->providable。一种方法是,Dijkstra是最优的,如果所有边都有相同的代价,那么BFS就是Dijkstra。还要注意,这返回的路径是相反的order@tucuxi我复制粘贴了他的代码并开始编辑,但忘了更改。谢谢:)关于反向路径,是的,但我不认为OP真的很难更改它。您仍然缺少return false;
,否则它将无法编译。完整的程序很好。而且,我从未见过数组。asList
用于单个elements@tucuxi签名是Arrays.asList(T…)
,它也可以与零元素一起使用。BFS实现将使用队列代替列表,对吗?@riista No。BFS将是一个迭代解决方案,而不是递归解决方案,并使用队列来保存下一个要访问的节点。@amit作为我自己的练习,您的答案中的DFS实现是否可以转换ibe到BFS算法?
public static void DFS(int[][] adj, boolean[] visited,
ArrayList<int> path, int n, int i, int o){
visited[i]= true;
if (i+1 != o) {
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
path.add(j);
DFS(adj, visited, n, j, o);
path.remove(path.size()-1);
}
}
} else {
// show path
for (int i : path) {
System.out.print(" " + i);
}
}
}
ArrayList<Integer> list = new ArrayList<>(); // this will have your path.
public static boolean DFS(int[][] adj, boolean[] visited, int n, int i, int o){
if(i==o){
list.add(o);
//System.out.println(i);
return true;
}
visited[i]= true;
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
if(DFS(adj, visited, n, j, o)){
list.add(0,j);
//System.out.println(j);
return true;
}
}
}
return false;
}
public static void main(String [] args){
int[][] adj = {
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0},
{1, 0, 0, 0, 1, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 1, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 0, 0, 1},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 1, 0, 0, 0}
};
boolean[] visited = new boolean[adj.length];
int n = adj.length;
int m = 1-1; //starting position
int o = 3-1; //ending position
System.out.println(DFS(adj, visited, n, m, o));
}
public static List<Integer> DFS(int[][] adj, boolean[] visited, int n, int i, int o){
visited[i]= true;
if (i == o) return new LinkedList<Integer>(Arrays.asList(i+1));
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
List<Integer> res = DFS(adj, visited, n, j, o);
if (res != null) {
res.add(0, i+1);
return res;
}
}
}
return null; //no path
}
[1, 4, 5, 6, 3]