[问题描述] 以一个 m*n 的长方阵表示迷宫,0 和 1 分别表示迷宫中的通路和障碍。设计一个程序, 对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 [基本要求] (1)实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求 得的通路以三元组(i, j, d)的形式输出,其中:(i, j)指示迷宫中的一个坐标,d 表示走到下 一坐标的方向。 (2)编写递归形式的算法,求得迷宫中所有可能的通路; (3)以方阵形式输出迷宫及其通路。(选做) [测试数据] 迷宫的测试数据示例如下:左上角(1,1)为入口,右下角(9,8)为出口。迷宫可任意设 定,也可随机产生。 这是近段时间做数据结构课程设计的题目,刚开始不会写这个题目的算法,准备到网上找一个模板来看看算法,结果找了一天都没有找到一个合适的,网上大部分都是C/C++写的,看了很久也没有看明白到底是怎么回事,后来熬夜把这个题目做出来了,想到大家在网上找这类代码都不容易,所以就发上来,供大家共享,写得不是很好,请见谅。。。。。。。。。
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);
}
}
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[][] ;
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} };
}