对于迷宫求解问题不是一个常规的遍历问题。在路径的叠加中要不端的判断点的连通性。在数据结构教材上有通用的解法
eg:迷宫
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 1, 1, 0, 1, 1, 1, 0, 1, 0
0, 1, 1, 0, 1, 1, 1, 0, 1, 0
0, 1, 1, 1, 1, 0, 0, 1, 1, 0
0, 1, 0, 0, 0, 1, 1, 1, 1, 0
0, 1, 1, 1, 0, 1, 1, 1, 1, 0
0, 1, 0, 1, 1, 1, 0, 1, 1, 0
0, 1, 0, 0, 0, 0, 0, 0, 1, 0
0, 0, 1, 1, 1, 1, 1, 1, 1, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
//0表示墙体,1表示可以行走;
迷宫求解问题主要运用了堆栈的性质
求迷宫中一条从入口到出口的路径的算法描述:
do
{
若当前位置可通
则 {
将当前位置插入栈顶;
若该位置时出口位置,则结束 ;
否则切换当前位置为东邻方块为新的当前位置;
}
否则
{
若栈不空且栈顶位置尚有其他方向未经探索,
则设定新的当前位置为沿顺时针方向旋转的栈顶位置的下一相邻模块
若栈不空但栈顶位置的四周均不可通
则 {
删去栈顶位置;
若栈不空,则重新测试新的栈顶位置
直至找到一个可通的相邻模块或出栈至栈空 ;
}
}
}while(栈不空)
这是教材的通解;
为了便于实际过程的理解,我改变了其中过程,算法如下:
初始化起点元素began;
初始化终点元素end;
起点元素入栈;
起点加入足迹;
while(栈顶元素不等于终点元素){
依据可通行原则在某个方向上创建next元素;
如果这个元素不为空{ set next元素的可通行;
next元素加入足迹
}
如果为空{
栈pop;
栈顶元素重新设置连通性;
}
}
java 代码实现:
为了方便我们声明一个Node类来保存连通性;
class Node {
private boolean Up;
private boolean Down;
private boolean Right;
private boolean Left;
private int x;
private int y;
public boolean isUp() {
return Up;
}
public void setUp(boolean up) {
Up = up;
}
public boolean isDown() {
return Down;
}
public void setDown(boolean down) {
Down = down;
}
public boolean isRight() {
return Right;
}
public void setRight(boolean right) {
Right = right;
}
public boolean isLeft() {
return Left;
}
public void setLeft(boolean left) {
Left = left;
}
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;
}
public Node(int x, int y) {
this.x = x;
this.y = y;
this.Up = true;
this.Down = true;
this.Right = true;
this.Left = true;
}
public boolean equals(Object obj) {//覆盖eauals(),便于List中的contains方法的调用
Node node=(Node) obj;
if (this.x == node.getX() && this.y == node.getY()) {
return true;
}
return false;
}
}
程序主体:
package migong;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class test {
//初始化迷宫;
static int[][] MAP = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 0, 1, 1, 1, 0, 1, 0 },
{ 0, 1, 1, 0, 1, 1, 1, 0, 1, 0 },
{ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 },
{ 0, 1, 0, 0, 0, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 0, 1, 1, 1, 1, 0 },
{ 0, 1, 0, 1, 1, 1, 0, 1, 1, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, };
static List foot = new ArrayList();//用于记录足迹;
public static void main(String[] args) {
Stack road = new Stack();
road.setSize(10*10);//设置栈的大小;
Node begain = new Node(1, 1);//加入初始位置;
foot.add(begain);//将 begain 加入足迹中
cheackConnect(begain);//检查连通性
road.push(begain);
Node end=new Node(8, 8);
while(!road.peek().equals(end)){
Node tmp=road.peek();
Node newNode=createNode(tmp);//依照栈顶元素来构建下一个位置;
if(newNode==null){//如果创建的元素为空,则此时的栈顶元素四个方向均不通
Node popNode=road.pop();//弹出栈顶元素;
cheackConnect(road.peek());//此时的栈顶元素,重新设置连通性。将上一个栈顶元素路径排除在外。
}else{
foot.add(newNode);
road.push(newNode);//移步下一个元素
}
}
while(!road.isEmpty()){//输出路径;
Node n=road.pop();
System.out.println(n.getX()+","+n.getY());
}
}
static Node createNode(Node peekNode){
Node res=null;
if(peekNode.isRight()){
res=new Node(peekNode.getX(), peekNode.getY()+1);//下标的加减来表示右边一个元素,*****二维数组可以看作一个x-y坐标轴顺时针旋转90°;故右边则是x,y+1;
cheackConnect(res);
return res;
}
if(peekNode.isDown()){
res=new Node(peekNode.getX()+1, peekNode.getY());
cheackConnect(res);
return res;
}
if(peekNode.isLeft()){
res=new Node(peekNode.getX(), peekNode.getY()-1);
cheackConnect(res);
return res;
}
if(peekNode.isUp()){
res=new Node(peekNode.getX()-1, peekNode.getY());
cheackConnect(res);
return res;
}
return res;
}
static void cheackConnect(Node node) {
Node right = new Node(node.getX(), node.getY()+1);//生成四个方向的块
Node down = new Node(node.getX()+1, node.getY());
Node left = new Node(node.getX(), node.getY()-1);
Node up = new Node(node.getX()-1, node.getY() );
if(NodeToArr(right)==0||foot.contains(right)){//foot.contains()和相邻块的值来确定出入Node的连通性;
node.setRight(false);
}
if(NodeToArr(down)==0||foot.contains(down)){
node.setDown(false);
}
if(NodeToArr(left)==0||foot.contains(left)){
node.setLeft(false);
}
if(NodeToArr(up)==0||foot.contains(up)){
node.setUp(false);
}
}
static int NodeToArr(Node n) {//Node转化为int[][]的值
return MAP[n.getX()][n.getY()];
}
}