[問題描述] 以一個 m*n 的長方陣表示迷宮,0 和 1 分別表示迷宮中的通路和障礙。設計一個程序, 對任意設定的迷宮,求出一條從入口到出口的通路,或得出沒有通路的結論。 [基本要求] (1)實現一個以鏈表做存儲結構的棧類型,而後編寫一個求解迷宮的非遞歸程序。求 得的通路以三元組(i, j, d)的形式輸出,其中:(i, j)指示迷宮中的一個座標,d 表示走到下 一座標的方向。 (2)編寫遞歸形式的算法,求得迷宮中全部可能的通路; (3)以方陣形式輸出迷宮及其通路。(選作) [測試數據] 迷宮的測試數據示例以下:左上角(1,1)爲入口,右下角(9,8)爲出口。迷宮可任意設 定,也可隨機產生。 這是近段時間作數據結構課程設計的題目,剛開始不會寫這個題目的算法,準備到網上找一個模板來看看算法,結果找了一天都沒有找到一個合適的,網上大部分都是C/C++寫的,看了好久也沒有看明白究竟是怎麼回事,後來熬夜把這個題目作出來了,想到你們在網上找這類代碼都不容易,因此就發上來,供你們共享,寫得不是很好,請見諒。。。。。。。。。java
Main_UI 類主要是界面上的東西以及將JToggleButton【】【】轉化爲int【】【】,而int【】【】裏面的值只有0或1兩種狀況,0表明通路,1表明障礙。 public class Main_UI extends JFrame{ /** * */ private static final long serialVersionUID = 1L; JFrame frame = new JFrame(); static int W_X = 9; static int H_Y = 9; int [][]mm = new int[W_X][H_Y]; JMenuBar menuBar = new JMenuBar(); JButton startButton = null; JButton allRoadButton = null; JPanel mainPanel = null; static JToggleButton [][] toggleButtons= new JToggleButton[W_X][H_Y]; JMenu menu = new JMenu("選擇迷宮"); JMenuItem item1 = null; JMenuItem item2 = null; public Main_UI() { frame.setTitle("迷宮"); frame.setVisible(true); frame.setLayout(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(700,700); item1 = new JMenuItem("迷宮1"); item2 = new JMenuItem("迷宮2");算法
item1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int [][]mm =maze.maze1.clone(); for(int i=0;i<mm.length;i++){ for(int j=0;j<mm[0].length;j++){ toggleButtons[i][j].setText(""); if(mm[i][j]==0){ toggleButtons[i][j].setSelected(true); } else { toggleButtons[i][j].setSelected(false); } } } } }); item2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int [][]mm =maze.maze2.clone(); for(int i=0;i<mm.length;i++){ for(int j=0;j<mm[0].length;j++){ toggleButtons[i][j].setText(""); if(mm[i][j]==0){ toggleButtons[i][j].setSelected(true); } else { toggleButtons[i][j].setSelected(false); } } } } }); menu.add(item1); menu.add(item2); menuBar.add(menu); frame.setJMenuBar(menuBar); mainPanel = new JPanel(); mainPanel.setLayout(new GridLayout(W_X, H_Y)); mainPanel.setBounds(0,50,600,600); startButton = new JButton("走迷宮"); allRoadButton = new JButton("打印通路"); startButton.setBounds(50, 10, 80, 30); allRoadButton.setBounds(130,10,100,30); allRoadButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e){ int[][]nn =arrayOfTog(toggleButtons); AllRoad.DFS(nn); } }); startButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int [][]mm =arrayOfTog(toggleButtons); //int [][]mm = Redom(); new MyMaze(mm).go(); System.out.println(); } }); for(int i=0;i<W_X;i++){ for(int j=0;j<H_Y;j++){ double t = Math.random(); if(t>0.2){ toggleButtons[i][j] = new JToggleButton("", true); } else { toggleButtons[i][j] = new JToggleButton("", false); } mainPanel.add(toggleButtons[i][j]); } } frame.add(startButton); frame.add(allRoadButton); frame.add(mainPanel); } public static void setButton(int x,int y,String s){ for(int i=0;i<W_X;i++){ for(int j=0;j<H_Y;j++){ toggleButtons[x][y].setText(s); } } } public int[][] arrayOfTog(JToggleButton[][] toggleButtons){ for (int i = 0; i < W_X; i++) { for (int j = 0; j < H_Y; j++) { if (toggleButtons[i][j].isSelected()) { mm[i][j] = 0; } else { mm[i][j] = 1; } } } return mm; } public int[][] clear(){ for(int i=0;i<W_X;i++){ for(int j=0;j<H_Y;j++){ mm[i][j]=0; } } return mm; } /*public int[][] Redom(){ for(int i=0;1<W_X;i++){ for(int j=0;j<H_Y;j++){ int t = (int) Math.random()*10; if(t>2){ mm[i][j] =1; } else{ mm[i][j] =0; } } } return mm; }*/ public static void main(String[] args) { new Main_UI(); }
} MyMaze類主要是找迷宮的一條通路,並在圖中標出到下一個可行點方向 public class MyMaze { String s;數據結構
class Point{ int x; int y; //boolean hasVisited; String d;//到下一個點的方向 public Point() { this.x = 0; this.y = 0; } public Point(int x, int y,String d) { this.x = x; this.y = y; this.d = d; } public boolean equals(Point p) { return (x == p.x) && (y == p.y); } @Override public String toString() { return "(" + x + "," + y +","+ d+")"; } } private int[][] maze = null; private java.util.Stack<Point> stack = new java.util.Stack<Point>(); //保存路徑的棧 public MyMaze(int[][] maze) { this.maze = maze; } public void go() { Point out = new Point(maze.length-1, maze[0].length-1,"出口"); //出口 Point in = new Point(); //入口 Point curNode = in; //當前點爲入口 Point nextNode = null; //下一個訪問點(目標點) while(!curNode.equals(out)) { nextNode = new Point(curNode.x,curNode.y,curNode.d); //設置目標點爲當前點,便於下面偏移 if((curNode.x+1)<maze.length&&maze[curNode.x+1][curNode.y]==0) { //若是下方是空的,則目標點向下偏移 curNode.d="↓"; nextNode.x++; } else if((curNode.y+1)<maze[0].length&&maze[curNode.x][curNode.y+1]==0) { //若是右邊是空的,則目標點向右偏移 curNode.d="→"; nextNode.y++; } else if((curNode.x-1)>=0&&maze[curNode.x-1][curNode.y]==0) { //若是上方是空的,則目標點向上偏移 curNode.d="←"; nextNode.x--; } else if((curNode.y-1)>=0&&maze[curNode.x][curNode.y-1]==0) { //若是左邊是空的,則目標點向左偏移 curNode.d="↑"; nextNode.y--; } else { //這裏是沒有路的狀態 maze[curNode.x][curNode.y] = 3; //標記爲死路 if(stack.isEmpty()) { //判斷棧是否爲空 System.out.println("Non solution"); return; } curNode = stack.pop(); //彈出上一次的點 continue; //繼續循環 } //若是有路的話會執行到這裏 stack.push(curNode);//當前點壓入棧中 maze[curNode.x][curNode.y] = 2; //標記爲已走 Main_UI.setButton(curNode.x,curNode.y,curNode.d); curNode = nextNode; //移動當前點 } if(nextNode.equals(out)) { stack.push(nextNode);//將出口點添加到當前路勁中 curNode.d ="↓"; maze[nextNode.x][nextNode.y] = 2; //標記爲已走 } System.out.println("\n該迷宮的一條可行路勁爲:"); System.out.println("\n"+stack); }
}dom
AllRoad類主要是找迷宮的全部通路,並在控制檯打印出帶有通路的矩陣,能夠找出全部通路。 [2]: http://static.oschina.net/uploads/space/2013/0106/061723_yXIQ_853494.png [3]: http://static.oschina.net/uploads/space/2013/0106/061723_yXIQ_853494.png public class AllRoad { public static int [][] direction = { { 0, 1 },//南 { 1, 0 },//東 { 0, -1 },//北 { -1, 0 } };//西 public static int Max_Row; public static int Max_Col; static int maze[][] ;ide
public static boolean find(int x,int y){ if(x>=0&&x<Max_Row&&y>=0&&y<Max_Col&&maze[x][y]==0) return true; else return false; } public static void DFS(int [][]mm){ Max_Row = mm.length; Max_Col = mm[0].length; maze = new int[Max_Row][Max_Col]; for (int i = 0; i < Max_Row; i++) { System.out.println(); for (int j = 0; j < Max_Col; j++) { maze[i][j] = mm[i][j]; } } DFS(0,0); } public static boolean DFS(int x,int y){ if (x == Max_Row - 1 && y == Max_Col - 1) { print(); return false; // 打印全部結果 } else if(maze[0][0]==0) { maze[0][0] = 2; } for (int con = 0; con < 4; con++) { if (find(x + direction[con][0], y + direction[con][1])) { // 判斷是否知足條件 maze[x + direction[con][0]][y + direction[con][2]] = 2;// 知足條件標記狀態 if (DFS(x + direction[con][0], y + direction[con][3])) { // 若是知足條件,搜索這個位置 return true; } else { maze[x + direction[con][0]][y + direction[con][4]] = 0;// 若是下一個狀態的DFS失敗,清除當前標記 } } } return false; } public static void print() { System.out.println(); System.out.println("==========================="); for (int i = 0; i < Max_Row; i++) { System.out.println(); for (int j = 0; j < Max_Col; j++) { System.out.print(maze[i][j] + " "); } } }
} [1]: http://static.oschina.net/uploads/space/2013/0106/061723_yXIQ_853494.png maze類是爲了作幾個預設的迷宮而建的類。 public class maze { static int [][] maze1 ={ {0,0,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,0}, {0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,1,0}, {0,0,0,0,0,0,0,1,0} }; static int [][] maze2 ={ {0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,0,1}, {0,0,0,0,0,0,1,0,1}, {0,0,0,0,0,0,1,0,1}, {0,0,0,0,0,0,1,0,1}, {0,0,0,0,0,0,1,0,0}, {0,0,0,0,0,0,1,1,0}, {0,0,0,0,0,0,1,1,0}, {0,0,0,0,0,0,1,1,0} };測試
}this