[问题描述] 以一个 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