深度优先和广度优先遍历迷宫

package didi;

import java.util.Stack;

/**
 * 深度优先迷宫问题
{{1,1,0,1},
{1,1,0,1},
{0,1,1,1},
{0,0,1,1}};

{1,1,1,0,1},
{1,0,1,0,1},
{1,0,1,1,1},
{1,1,0,1,1},
{0,0,0,1,1},
 * @author yanjie
 *
 */
public class DFPath {

    public static void main(String[] args) {
    	//迷宫点,1表示可走,0表示不可走,(0,0)为入口,(0,3)为出口
        int[][] maze = {{1,1,1,0,1},
		        		{1,0,1,0,1},
		        		{1,0,1,1,1},
		        		{1,1,0,1,1},
		        		{0,0,0,1,1}};
        //可以走的方向,上下左右
        int[][] move = {{0,-1},{0,1},{-1,0},{1,0}};
        //使用栈s存储路径
        Stack<Point> s = new Stack<Point>();
        int a = path(maze, move, s);
        if(a==1){
        	while(!s.isEmpty()){//输出是倒的
            	Point step = s.pop();
                System.out.println(step.x+" "+step.y);
            }
        }
    }
    /**
     * 将(0,0)点入栈,将maze[0][0]=-1,表示点(0,0)已经访问过了
     * 维护一个当前点temp,第一次temp为栈顶,判断temp其周围四个点是否可达,
     * 如果可达则将temp更新为可达的那个点,并将maze路径中对应位置标记位-1,表示已经访问过
     * 如果不可达则弹出栈顶,取栈下一个元素
     * 当stack不为空时
     * @param maze
     * @param move
     * @param s
     * @return
     */
    public static int path(int[][] maze,int[][] move,Stack<Point> s){
    	Point temp = new Point(0,0); //起点
    	maze[0][0]=-1;//表示已经访问过这个点了
    	int m=maze.length-1,n=maze[0].length-1;
        s.push(temp);
        //栈不为空
        while(!s.isEmpty()){
        	//取栈顶的点
            temp = s.peek();
            int d = 0;
            //遍历上下左右四个方向
            while(d<4){
                int i = temp.x + move[d][0];
                int j = temp.y + move[d][1];
                //该点不越界,且可达
                if(i>=0 && j>=0 && i<=m && j<=n && maze[i][j]==1){
                    temp = new Point(i,j); //到达新点
                    s.push(temp);
                    maze[i][j] = -1;  //到达新点,标志已经到达
                    if(i == 0 && j == n){
                        return 1;  //到达出口,迷宫有路,返回1
                    }else{
                        d = 0;  //此时temp点已经更新为新点了,重新初始化方向
                    }
                }else{
                    d++; //改变方向
                }
            }
            //遍历其周围四个点,都没法通过,则弹出这个点
            s.pop();
        }
        return 0;
    }
    static class Point{
        int x,y;
        public Point(int x,int y) {
            this.x = x;//横坐标
            this.y = y;//纵坐标
        }
    }
}
package didi;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * 广度优先求解迷宫问题
{{1,1,0,1},
{1,1,0,1},
{0,1,1,1},
{0,0,1,1}};

{1,1,1,0,1},
{1,0,1,0,1},
{1,0,1,1,1},
{1,1,0,1,1},
{0,0,0,1,1},
 * @author yanjie
 *
 */
public class BFPath {

    public static void main(String[] args) {
    	//迷宫点,1表示可走,0表示不可走,(0,0)为入口,(0,3)为出口
        int[][] maze = {{1,1,1,0,1},
		        		{1,0,1,0,1},
		        		{1,0,1,1,1},
		        		{1,1,0,1,1},
		        		{0,0,0,1,1}};
        //可以走的方向,上下左右
        int[][] move = {{0,-1},{0,1},{-1,0},{1,0}};
        //使用队列s存储路径
        
        path(maze, move);
    }
    /**
     * 将(0,0)点入栈,将maze[0][0]=-1,表示点(0,0)已经访问过了
     * 维护一个当前点temp,第一次temp为栈顶,判断temp其周围四个点是否可达,
     * 如果可达则将temp更新为可达的那个点,并将maze路径中对应位置标记位-1,表示已经访问过
     * 如果不可达则弹出栈顶,取栈下一个元素
     * 当stack不为空时
     * @param maze
     * @param move
     * @param s
     * @return
     */
    public static void path(int[][] maze,int[][] move){
    	Queue<Point> q = new LinkedList<Point>();
    	q.add(new Point(0,0,null));
    	maze[0][0]=-1;//表示已经访问过这个点了
    	int m=maze.length-1,n=maze[0].length-1;
        
        //队列不为空
        while(!q.isEmpty()){
        	//出队
        	Point temp = q.poll();
            int x = temp.x;
            int y = temp.y;
            int d = 0;//
            while(d<4){
                int i = x + move[d][0];
                int j = y + move[d][1];
                //该点不越界,且可达
                if(i>=0 && j>=0 && i<=m && j<=n && maze[i][j]==1){
                	Point point = new Point(i,j,temp); //新节点指向temp
                	if(x==1 && y==4){
                		System.out.println(i+"+"+j);
                	}
                    q.add(point);
                    maze[i][j] = -1;  //到达新点,标志已经到达
                    
                    if(x == 0 && y == n){
                    	//到达出口,迷宫有路,沿着当前节点往前找
                    	System.out.println("找到!");
                    	Point cur = temp;
                    	while(cur!=null){
                    		System.out.println(cur.x+" "+cur.y);
                    		cur = cur.pre;
                    	}
                    }
                }else{
                    d++; //改变方向
                }
            }
        }
    }
    static class Point{
        int x,y;
        Point pre;//前驱节点
        public Point(int x,int y,Point pre) {
            this.x = x;//横坐标
            this.y = y;//纵坐标
            this.pre = pre;//前驱节点
        }
    }
}


  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值