Java中栈.回溯.迷宫问题求解

考虑使用一个二维数组表示迷宫.所有的通路用0表示,墙用1表示,出口用9表示,入口用6表 示,已经过点用3表示.输出走出迷宫的过程.

从这个问题的求解过程中可以简单总结出两个算法,一是探路过程,二是输出路线.

1.探路过程

探路过程算法可归纳为:

[1]从入口位置开始,检查东西南北四个方向上的通路,如果发现出口则成功退出,否则将所 有通路坐标压入栈;

[2]从栈中取出一个坐标,将其标记为当前位置(标记数字3),再次判断通路情况;

[3]如此进行,直到发现出口则成功退出,若栈空而且未发现出口,则失败退出.

这里使用到的回溯过程可描述为:

每到达一点时,会将所有可能的通路坐标(标记数字0的节点)压入栈.所以当到达一点,而不 存在可能的通路时,自然没有相应的坐标压入栈,而此时便从栈中取出上一个点所压入的可能 的一个通路坐标,并继续作通路判断,这便是一个回溯的过程.

2.输出某一较短路线

将所有在探路过程中经过的点(标记数字3的节点)按实际探路路线存入队列,对头为入口, 队尾为出口.这些点可能存在绕路的情况,所以可用下面的算法输出某一较短路线.

[1]将队尾(出口)节点设置为当前判断节点;

[2]从当前判断节点(x,y)的前驱节点开始,向前遍历队列,如果发现相邻节点(其坐标可以 为(x+1,y),(x-1,y),(x,y+1),(x,y-1)之一),则删除该相临节点至当前判断节点的前驱节点之 间的所有节点;

[3]将该相临节点设置为当前判断节点,继续判断相临节点;

[4]当当前判断节点为队头节点时退出.

该算法所得到的路线不一定是最短路线,想得到最短路线,可考虑使用树结构将所有由出口 至入口的路线保留为一子树,树高最短的子树即为最短路线.但此算法可保证所得路线不会存 在绕路情况.

3.表示节点坐标的类

public class MazeCell {   private int x, y;//表示x轴y轴坐标   public MazeCell() {   }   public MazeCell(int i, int j) {     x = i;     y = j;   }   public boolean equals(Object o) {     if (!(o instanceof MazeCell))       return false;     MazeCell cell = (MazeCell) o;     return cell.x == x && cell.y == y;   }   public String toString() {     return x + "," + y;   }   public int getX() {     return x;   }   public void setX(int x) {     this.x = x;   }   public int getY() {     return y;   }   public void setY(int y) {     this.y = y;   }}

4.所使用的栈数据结构

import java.util.LinkedList;public class Stack {   private LinkedList sTorage = new LinkedList();   /** 入栈 */   public void push(T v) {     sTorage.addFirst(v);   }   /** 出栈,但不删除 */   public T peek() {     return sTorage.getFirst();   }   /** 出栈 */   public T pop() {     return sTorage.removeFirst();   }   /** 栈是否为空 */   public boolean empty() {     return sTorage.isEmpty();   }   /** 打印栈元素 */   public String toString() {     return sTorage.toString();   }}

5.求解迷宫问题

package net.zj.maze;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.util.IteraTor;import java.util.LinkedList;import java.util.List;import java.util.ListIteraTor;public class Maze {    private int rows = 0, cols = 0;// 迷宫的行数与列数    private char[][] sTore, path;// 迷宫矩阵    private MazeCell currentCell, exitCell = new MazeCell(),            entryCell = new MazeCell();// 当前节点,出口节点,入口节点    private static final char EXIT = '9', ENTRY = '6', VISITED = '3';// 出口标记,入口标记,已经过节点标记    private static final char PASS = '0', WALL = '1';// 通路标记,墙标记    private Stack mazeStack = new Stack();// 探路过程所使用栈    private List currentList = new LinkedList();// 路经的路线队列    public Maze() {        // 构造迷宫        int row = 0, col = 0;        Stack mazeRows = new Stack();        InputStreamReader isr = new InputStreamReader(System.in);        BufferedReader buffer = new BufferedReader(isr);        System.out.println("Enter a rectangular maze using the following"                + " characters: /n6-entry/n9-exit/n1-wall/n0-passage/n"                + "Enter one line at a time; end with Ctrl-d;");        try {            String str = buffer.readLine();            while (str != null) {                row++;                cols = str.length();                str = "1" + str + "1";                mazeRows.push(str);                if (str.indexOf(EXIT) != -1                                               思想如钻子,必须集中在一点钻下去才有力量

Java中栈.回溯.迷宫问题求解

相关文章:

你感兴趣的文章:

标签云: