迷宫问题 非递归(java版)

来源:互联网 发布:linux守护进程编写 编辑:程序博客网 时间:2024/05/22 07:07

一、简要
偶尔接触到迷宫问题发现挺有趣的,所以开始研究了一下。我觉得这个问题的关键是:

  • 怎么设计这个迷宫?
  • 怎么利用栈的特点来解决这个问题?
  • 在迷宫行走怎么更改迷宫的方向?
  • 怎么寻找迷宫路径?以及怎么才算找到迷宫路径?

二、思路

通过上面的问题关键,在脑中可以构造一个大体的思路:

  • 首先创建一个迷宫maze,对于迷宫可以采用mxn的一个二维数组来设计。
  • 创建一个mazenode节点类来控制二维数组中的每一个节点,另外还需要构造一个函数来设计每个节点(东、南、西、北)的可行性。
  • 为了保证在任何位置上都能沿原路退回,所以需要用一个后进先出的结构来保存从入口到当前位置的路径,因此在求迷宫通路的算法中要应用“栈”的思想,所以必须设计一个栈出来,用来存储“当前路径”,即“在搜索过程中某一时刻所在图中某个方块位置”。
  • 然后就可以开始寻找迷宫路径了,从迷宫的入口节点开始入栈,来寻找它下一个位置,如果当前位置的下个位置(东、南、西、北)可以走,那么就把当前位置的下个位置的行走状态改为不可以行走,把当前位置也改为不可以行走,(因为都是从那里走回来的不能再走回去了,不然就是一个死循环了),然后把下个位置节点入栈;继续寻找,如果遇见了死胡同,那么就开始出栈。如果入栈的节点的行列数和迷宫行列数相等,说明我们已经找到出口,可以跳出循环。或者另一种情况就是一直遇见死胡同,一直出栈,直到栈空,那就说明该迷宫没有路径。
  • 最后就可以出栈打印出迷宫路径。
  • 以上操作都是个人想法,如有错误还望指正。

三、java代码实现

//常数类方便操作public class Constant {public static final int WAY_NUMBER = 4;    //表示路径可以行走    public static final int WAY_ENABLE = 1;    //表示路径不可以行走    public static final int WAY_DISABLE = 0;    //迷宫节点的四个方向    public static final int WAY_EAST = 0;    public static final int WAY_SOUTH = 1;    public static final int WAY_WEST = 2;    public static final int WAY_NORTH = 3;}
//迷宫节点类public class MazeNode {    private int value;    private int i;    private int j;    private int[] pathState;    public MazeNode(int value, int i, int j){        this.value = value;        this.i = i;        this.j = j;        //初始化节点的四个方向的路径信息,都初始化成不能行走        pathState = new int[Constant.WAY_NUMBER];        for(int k=0; k<pathState.length; ++k){            pathState[k] = Constant.WAY_DISABLE;        }    }    //设置迷宫行走状态的构造函数    public void setPathState(int path, int state){        pathState[path]=state;    }    //获取迷宫行走状态的构造函数    public int getPathState(int path){        return pathState[path];    }           public int getValue() {        return value;    }    public void setValue(int value) {        this.value = value;    }    public int getRow() {        return i;    }    public void setRow(int i) {        this.i = i;    }    public int getCol() {        return j;    }    public void setCol(int j) {        this.j = j;    }}
import java.util.Arrays;import java.util.Scanner;//创建栈class SqStack{    private MazeNode[] stack;    private int top;    public SqStack(){        top = 0;        stack = new MazeNode[50];    }    //push要支持stack的内存增长操作,一次性增长2倍    public void push(MazeNode node) {    if(full())        resize();   this.stack[this.top++]=node;   }    public void pop() {        if(empty())         return ;        this.top--;    }    public MazeNode top() {        //return null;        return this.stack[this.top-1];    }    public boolean empty() {        //return false;        return this.top == 0;    }    public boolean full() {        //return false;        return this.top == 0;    }    private void resize(){        this.stack=Arrays.copyOf(this.stack, this.stack.length*2);    } }//构造迷宫类class Maze{    private int row;    private int colum;    private MazeNode[][] mazePath;//迷宫节点,二维数组    private SqStack stack;    public Maze(int row, int colum){        this.row = row;        this.colum = colum;        mazePath = new MazeNode[this.row][this.colum];        stack = new SqStack();    }    public void setPath(int i, int j, int value){        mazePath[i][j] = new MazeNode(value, i, j);    }        //该函数主要用来更改迷宫节点四个方向的行走状态    public void adjustMazePath(){        for(int i=0;i<this.row;i++){            for(int j=0;j<this.colum;j++){                //先调整最层路径                if(mazePath[i][j].getValue()==0){                  //东                    if(j<this.colum-1&&mazePath[i][j+1].getValue()==0){                        mazePath[i][j].setPathState(Constant.WAY_EAST,Constant.WAY_ENABLE);                    }                    //南                    if(i<this.row-1&&mazePath[i+1][j].getValue()==0){                        mazePath[i][j].setPathState(Constant.WAY_SOUTH,Constant.WAY_ENABLE);                    }                    //西                    if(j>0&&mazePath[i][j-1].getValue()==0){                        mazePath[i][j].setPathState(Constant.WAY_WEST,Constant.WAY_ENABLE);                    }                    //北                    if(i>0&&mazePath[i-1][j].getValue()==0){                        mazePath[i][j].setPathState(Constant.WAY_NORTH,Constant.WAY_ENABLE);                    }                }            }        }}           //开始寻找迷宫路径    public void findMazePath(){        System.out.println("正在寻找迷宫路径。。。");        this.stack.push(mazePath[0][0]);//入口传入栈        int i=0,j=0;        while(!this.stack.empty()){        MazeNode top=this.stack.top();        //如果top的行列数等于Maze的行列书,说明就已经找到出口        if(i ==this.row-1&&j==this.colum-1){            break;        }        //判断东        if(top.getPathState(Constant.WAY_EAST)==Constant.WAY_ENABLE){            mazePath[i][j].setPathState(Constant.WAY_EAST,  Constant.WAY_DISABLE);            mazePath[i][j+1].setPathState(Constant.WAY_WEST,  Constant.WAY_DISABLE);             this.stack.push(mazePath[i][j+1]);             j++;             continue;        }        //判断南        if(top.getPathState(Constant.WAY_SOUTH)==Constant.WAY_ENABLE){            mazePath[i][j].setPathState(Constant.WAY_SOUTH,  Constant.WAY_DISABLE);            mazePath[i+1][j].setPathState(Constant.WAY_NORTH,  Constant.WAY_DISABLE);            this.stack.push(mazePath[i+1][j]);            i++;            continue;        }        //判断西        if(top.getPathState(Constant.WAY_WEST)==Constant.WAY_ENABLE){            mazePath[i][j].setPathState(Constant.WAY_WEST,  Constant.WAY_DISABLE);            mazePath[i][j-1].setPathState(Constant.WAY_EAST,  Constant.WAY_DISABLE);             this.stack.push(mazePath[i][j-1]);             j--;             continue;        }        //判断北        if(top.getPathState(Constant.WAY_NORTH)==Constant.WAY_ENABLE){            mazePath[i][j].setPathState(Constant.WAY_NORTH,  Constant.WAY_DISABLE);            mazePath[i-1][j].setPathState(Constant.WAY_SOUTH,  Constant.WAY_DISABLE);            this.stack.push(mazePath[i-1][j]);             i--;            continue;        }        this.stack.pop();    }       if(this.stack.empty()){        System.out.println("从左上角入口到右下角出口不存在有效路径   、、、、");    }       }    //打印最终的迷宫路径信息    public void showMazePath(){        while(!this.stack.empty()){            MazeNode top=this.stack.top();            int i=top.getRow();            int j=top.getCol();            mazePath[i][j].setValue(2);            //System.out.printf("<%d,%d>->",this.stack.top().getRow(),this.stack.top().getCol());             this.stack.pop();        }        System.out.println("路径已找到,输入如下(2代表行走的路径):");        for(int i=0;i<this.row;i++){            for(int j=0;j<this.colum;j++){                System.out.print(mazePath[i][j].getValue()+" ");            }            System.out.println();            }    }}public class TestMazePathDemo {    public static void main(String[] args) {        // TODO Auto-generated method stub        Scanner scan = new Scanner(System.in);        System.out.print("请输入迷宫的行列数(m * n):");        int row = scan.nextInt();        int col = scan.nextInt();        //maze现在代表的就是整个迷宫        Maze maze = new Maze(row, col);        System.out.println("请输入迷宫的路径:");        for(int i=0; i<row; ++i){            for(int j=0; j<col; ++j){                int data = scan.nextInt();                maze.setPath(i, j, data);            }        }        //以上代码,就把整个迷宫路径的信息都设置到maze对象里面了        //该函数主要用来更改迷宫节点四个方向的行走状态        maze.adjustMazePath();        //开始寻找迷宫路径        maze.findMazePath();        //打印最终的迷宫路径信息        maze.showMazePath();    }}
原创粉丝点击