深度優先和廣度優先遍歷迷宮
阿新 • • 發佈:2019-01-02
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;//前驅節點 } } }