迷宫问题的非递归解法

迷宫问题一般可以建模为一个二维数组,二维数组的值表示位置(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 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)



猜你喜欢

转载自blog.csdn.net/to_be_to_thought/article/details/80208954
今日推荐