迷宫问题一般可以建模为一个二维数组,二维数组的值表示位置(i,j)是否可以通行,将位置数据结构设为
每个格网的数据结构
public class Loc {
int row_idx;
int col_idx;
Loc pre;
boolean pass;
boolean visited;
public Loc(int i,int j,Loc pre,boolean pass,boolean visited)
{
this.row_idx=i;
this.col_idx=j;
this.pre=pre;//记录该路径的前驱,以便记录整条路径
this.pass=pass;
this.visited=visited;//是否被访问过
}
//确认位置loc和this的位置是否一样(包含引用相同和深拷贝相同两种)
public boolean equals(Loc loc)
{
if(this.row_idx==loc.row_idx && this.col_idx==loc.col_idx)
return true;
else
return false;
}
//位置输出
public String toString()
{
return "("+this.row_idx+","+this.col_idx+")";
}
整个迷宫数据结构:
public class Maze {
Loc[][] maze;
//迷宫类构造函数,用二维数组初始化一个迷宫
public Maze(int[][] nums)
{
int len1=nums.length;
int len2=nums[0].length;
this.maze=new Loc[len1][len2];
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(nums[i][j]==1)
this.maze[i][j]=new Loc(i,j,null,true,false);
else
this.maze[i][j]=new Loc(i,j,null,false,false);
}
}
}
//判断位置是否在迷宫内部
public boolean inMaze(int row_idx,int col_idx)
{
int rows=this.maze.length;
int cols=this.maze[0].length;
if(row_idx>=0 && row_idx<rows && col_idx>=0 && col_idx<cols)
return true;
else
return false;
}
public boolean inMaze(int row_idx,int col_idx)
{
int rows=this.maze.length;
int cols=this.maze[0].length;
if(row_idx>=0 && row_idx<rows && col_idx>=0 && col_idx<cols)
return true;
else
return false;
}
public String Route2String(Loc end)
{
Loc p=end;
String route="";
while(p!=null)
{
route=p.toString()+route;
p=p.pre;
}
return "路线为:"+route;
}
使用深度优先搜索和广度优先搜索都可以求解,深度优先搜索就像一条蛇在迷宫中搜索,一直向前试探如果前路不通则后退一格,从当前格子的其他方向再进行搜索。广度优先搜索相当于小虫子在迷宫中走,每次遇到一个岔路口就分身,有几条岔路就分成几个虫子继续向前。
栈实现的深度优先搜索:
public Loc DFS_route(Loc start,Loc end)
{
int[][] dirs={{-1,0},{1,0},{0,-1},{0,1}};
LinkedStack<Loc> stack=new LinkedStack<Loc>();
stack.push(start);
start.visited=true;
while(!stack.isEmpty())
{
Loc temp=stack.pop();
for(int dir=0;dir<4;dir++)
{
int new_r=temp.row_idx+dirs[dir][0];
int new_c=temp.col_idx+dirs[dir][1];
if( this.inMaze(new_r,new_c) && !this.maze[new_r][new_c].visited && this.maze[new_r][new_c].pass)
{
stack.push(this.maze[new_r][new_c]);
this.maze[new_r][new_c].visited=true;
this.maze[new_r][new_c].pre=temp;
if(this.maze[new_r][new_c].equals(end))
return end;
}
}
}
return null;
队列实现的广度优先搜索:
public Loc BFS_route(Loc start,Loc end)
{
int[][] dirs={{-1,0},{1,0},{0,-1},{0,1}};
LinkedQueue<Loc> q=new LinkedQueue<Loc>();
q.enqueue(start);
start.visited=true;
while(!q.isEmpty())
{
Loc temp=q.dequeu();
for(int dir=0;dir<4;dir++)
{
int new_r=temp.row_idx+dirs[dir][0];
int new_c=temp.col_idx+dirs[dir][1];
if( this.inMaze(new_r,new_c) && !this.maze[new_r][new_c].visited && this.maze[new_r][new_c].pass)
{
q.enqueue(this.maze[new_r][new_c]);
this.maze[new_r][new_c].visited=true;
this.maze[new_r][new_c].pre=temp;
if(this.maze[new_r][new_c].equals(end))
return end;
}
}
}
return null;
}
测试程序:
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] nums={{1,1,1,0,0,1,1},{1,1,1,0,0,1,0},{0,0,1,0,0,1,0},{1,1,1,1,1,1,0},
{0,1,0,0,0,1,0},{1,1,0,0,0,0,1},{1,1,1,1,1,1,1}};
Maze m=new Maze(nums);
Loc start=m.maze[0][0];
Loc end=m.maze[6][6];
System.out.println(m.Route2String(m.DFS_route(start,end)));
Maze n=new Maze(nums);
start=n.maze[0][0];
end=n.maze[6][6];
Loc e=n.BFS_route(start,end);
System.out.println(m.Route2String(e));
System.out.println();
}
输出:
路线为:(0,0)(1,0)(1,1)(1,2)(2,2)(3,2)(3,1)(4,1)(5,1)(6,1)(6,2)(6,3)(6,4)(6,5)(6,6)