JAVA泛型及栈应用之简单迷宫

JAVA泛型及栈应用之简单迷宫

将泛型与栈结合结合之后,可以高效解决一些数据结构中的问题,其中,走迷宫便是我们最常遇到的一类。再此之前,需要对栈以及泛型有所了解:>JAVA泛型与栈应用<
这里,先以简单迷宫为例:
假设现在有一个6X6的矩形迷宫,1表示通路,其他表示无路。
JAVA泛型及栈应用之简单迷宫_第1张图片
如果以[5][2]为入口,那么,走出迷宫的路径应该为:
JAVA泛型及栈应用之简单迷宫_第2张图片
那该如何用代码来走呢?
思路应该如下:

  • 1.判断给定入口是否为真入口;
  • 2.走下一步,在走之前判断下一步是否为通路;
  • 3.判断是否已经到达出口;
  • 4.循环寻路;

寻路其实就是去试探上下左右四个方向是否通路,如果这里每次以上,左,右,下为序寻路,那么最终路径应该为:
JAVA泛型及栈应用之简单迷宫_第3张图片

好,思路已经有了,现在来写代码吧。
首先,创建一个类Position,用来存放坐标,以后栈就用来放一个个Position实例化的对象。

class Position {
    private int x;//横坐标
    private int y;//纵坐标
    public Position(int x, int y) {//构造
        this.x = x;
        this.y = y;
    }
    public int getX() {//getter方法,用来将来取坐标
        return x;
    }
    public int getY() {
        return y;
    }
    public void setX(int x) {//这里既用构造,又用setter方法,方便在后面写入
        this.x = x;
    }
    public void setY(int y) {
        this.y = y;
    }
}

根据前面的思路,可以写三个方法,分别用来判断入口是否有效,是否到达出口,是否为通路
判断入口方法isEntry(),返回值为boolean;,该点应该为1,且在四个边界其中一个上

public static boolean isEntry(Position entry,int [][] maze,int r,int l) {//入口是否合法
        if (maze[entry.getX()][entry.getY()] == 1 && (entry.getX() ==0 ||entry.getX() == r-1) || (entry.getY() ==0 ||entry.getY() == r-1)) {
            return true;
        }
        return false;
        }

判断通路方法isPath(),返回值为boolean,该点的值应该为1,且不能出边界。

public static boolean isPath(int [][] maze,Position cur,int r,int l) {
        if (maze[cur.getX()][cur.getY()] == 1 && (cur.getX() >=0 ||cur.getX() <= r-1) && (cur.getY() >=0 ||cur.getY() <= r-1))
            return true;
        return false;

    }

出口判断isExit(),返回值也为boolean;跟入口判断极为相似,在边界,但不是在入口的位置。

public static boolean isExit(int [][] maze,Position cur,Position entry,int r,int l) {//是否为出口
        if ((cur.getX() !=entry.getX() && cur.getY() !=entry.getY())  && (cur.getX() ==0 ||cur.getX() == r-1) || (cur.getY() ==0 ||cur.getY() == r-1))
            return true;
        return false;

    }

全部代码,因为设定1为通路,将走过的点置为2,表示已经走过来,当走到末路,往回走时将其设置成3,这样就可以看到走过的路径,这里的2和3可以随意设置,并无特殊含义。

package maze;

//建栈
interface Stack {
    void stackPush(T posi);// 入

    void stackPop();// 出

    T stackTop();// 取

    int stackSize();// 数量

    boolean stackEmpty();// 为空否
}

class StackImp implements Stack {
    // 栈要放啥?头,尾,数量
    private int size;
    private Node first;
    private Node last;

    private class Node {
        private T position;
        private Node next;

        public Node(T position, StackImp.Node next) {
            this.position = position;
            this.next = next;
        }

    }

    @Override
    public void stackPush(T posi) {
        Node tmp = this.first;
        Node newNode = new Node(posi, null);
        this.last = newNode;
        if (null == this.first) {
            this.first = newNode;
        } else {
            while (null != tmp.next) {
                tmp = tmp.next;
            }
            tmp.next = newNode;
        }
        ++this.size;
    }

    @Override
    public void stackPop() {
        // 只剩一个时
        // 剩多个时
        Node tmp = this.first;
        if (null == tmp.next || null == tmp) {

            this.first = null;
            this.last = null;
            this.size = 0;
            return;
        }
        while (null != tmp.next.next) {
            tmp = tmp.next;
        }
        tmp.next = null;
        this.last = tmp;
        --this.size;
    }

    @Override
    public T stackTop() {
        if (this.first == null) {
            return null;
        } else {
            return (T)this.last.position;
        }
    }

    @Override
    public int stackSize() {
        return this.size;
    }

    @Override
    public boolean stackEmpty() {
        if (0 == this.size) {
            return true;
        } else {
            return false;
        }

    }
}

class Position {//坐标类
    private int x;
    private int y;
    public Position(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
    public void setX(int x) {
        this.x = x;
    }
    public void setY(int y) {
        this.y = y;
    }
}
public class Test {

    public static void main(String[] args) {
        Stack  stack = new StackImp();

        int [][] arr = {
                { 0, 0, 0, 0, 0, 0 },
                { 0, 0, 1, 0, 0, 0 },
                { 0, 0, 1, 0, 0, 0 },
                { 0, 0, 1, 1, 1, 0 },
                { 0, 0, 1, 0, 1, 1 },
                { 0, 0, 1, 0, 0, 0 } };
        Position entry = new Position(5, 2);
        maze(stack,arr,entry);
    }

    //++++++++++++++++++++++++++++++++++++以下为走迷宫 ++++++++++++++++++++++++++++++++++++++++++++

        public static void maze(Stack stack,int arr[][],Position entry) {
        int r = 6;
        int l = 6;
        int [][] maze= new int [r][l];
        for (int i = 0 ; i < r ; i ++) {//初始化走迷宫数组
            for (int j = 0; j < l; j ++) {
                maze[i][j] = arr[i][j];
            }
        }
        //需要几个判断方法
        //1.传入的坐标是否为真入口;
        //2.当前坐标是否为出口;
        //3.下一步要走的坐标是否可走;
        if (!isEntry(entry, maze, r, l)) {
            return;
        }
        Position cur = new Position(entry.getX(), entry.getY());
        Position tmp1 = new Position(entry.getX(), entry.getY());
        stack.stackPush(tmp1);
        maze[entry.getX()][entry.getY()] = 2;//判断过就相当于走过了,置为2
        while (!isExit(maze, cur, entry, r, l)) {


            //up
            Position tmp = new Position(entry.getX(), entry.getY());//这里有个小坑,tmp是必须每次都新实例化的,要不然就会一直使用一个tmp对象,最后栈中放的都是同一个坐标。
            tmp.setX(cur.getX()-1);
            tmp.setY(cur.getY());
            if (isPath(maze, tmp, r, l)) {
                maze[tmp.getX()][tmp.getY()] = 2;
                cur.setX(tmp.getX());
                stack.stackPush(tmp);
                System.out.println(stack.stackTop().getX() + " "+stack.stackTop().getY());
                printMaze(maze);
                continue;
            }
            //left
            tmp.setX(cur.getX());
            tmp.setY(cur.getY()-1);
            if (isPath(maze, tmp, r, l)) {
                maze[tmp.getX()][tmp.getY()] = 2;
                cur.setY(tmp.getY());
                stack.stackPush(tmp);
                System.out.println(stack.stackTop().getX() + " "+stack.stackTop().getY());
                printMaze(maze);
                continue;
            }
            //right
            tmp.setX(cur.getX());
            tmp.setY(cur.getY()+1);
            if (isPath(maze, tmp, r, l)) {
                maze[tmp.getX()][tmp.getY()] = 2;
                cur.setY(tmp.getY());
                stack.stackPush(tmp);
                System.out.println(stack.stackTop().getX() + " "+stack.stackTop().getY());
                printMaze(maze);
                continue;
            }
            //down
            tmp.setX(cur.getX()+1);
            tmp.setY(cur.getY());
            if (isPath(maze, tmp, r, l)) {
                maze[tmp.getX()][tmp.getY()] = 2;
                cur.setX(tmp.getX());
                stack.stackPush(cur);
                System.out.println(stack.stackTop().getX() + " "+stack.stackTop().getY());
                printMaze(maze);
                continue;
            }
            //走了,或者下一步走不了
            cur = stack.stackTop();
            printMaze(maze);
            maze[cur.getX()][cur.getY()] = 3;
            stack.stackPop();
        }
        System.out.println("I'm out!");
    }
    public static void printMaze(int [][] maze) {
        for (int i = 0 ; i < 6 ; i ++) {
            for (int j = 0; j < 6; j ++) {
                System.out.print(maze[i][j]+ " ");
            }
            System.out.println();
        }
        System.out.println();
    }
    public static boolean isExit(int [][] maze,Position cur,Position entry,int r,int l) {//是否为出口
        if ((cur.getX() !=entry.getX() && cur.getY() !=entry.getY())  && (cur.getX() ==0 ||cur.getX() == r-1) || (cur.getY() ==0 ||cur.getY() == r-1))
            return true;
        return false;

    }
    public static boolean isEntry(Position entry,int [][] maze,int r,int l) {//入口是否合法
        if (maze[entry.getX()][entry.getY()] == 1 && (entry.getX() ==0 ||entry.getX() == r-1) || (entry.getY() ==0 ||entry.getY() == r-1)) {
            return true;
        }
        return false;

    public static boolean isPath(int [][] maze,Position cur,int r,int l) {
        if (maze[cur.getX()][cur.getY()] == 1 && (cur.getX() >=0 ||cur.getX() <= r-1) && (cur.getY() >=0 ||cur.getY() <= r-1))
            return true;
        return false;

    }
}

这里要特别注意while语句Position tmp = new Position(entry.getX(), entry.getY());这一句,这里有个小坑,tmp是必须每次都新实例化的,要不然就会一直引用同一个tmp对象,最后栈中放的都是同一个坐标。

while (!isExit(maze, cur, entry, r, l)) {


            //up
            Position tmp = new Position(entry.getX(), entry.getY());
            tmp.setX(cur.getX()-1);
            tmp.setY(cur.getY());
            if (isPath(maze, tmp, r, l)) {
            ...

>源码<

如果不想看JAVA语言,可以选择C语言版>C语言用栈实现走迷宫源码<

你可能感兴趣的:(经验,学习,Java基础,算法实例)