问题:求解迷宫问题:求入口到出口的路径,通常用的是“穷举求解”的方法。即从入口出发,顺着某一方向走,若能走通,则继续往前走,如果走不通,原路退回,换一个方向继续探索,直到所有的通路都探索完毕为止。
第一步:将迷宫本身抽象成一个二维数组;
int[][] maze = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 1, 1, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 1, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 1, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 1, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 0, 1, 1},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
第二步:抽象一个具体的位置信息模块;
public class Position {
private int lineNum; //行号
private int columnNum; //列号
//每一个位置会有4个方向的邻近位置,上下左右 0,1,2,3
private int nextPostionNum; //下一步可走方位的方向号
public Position() {
}
public Position(int lineNum, int columnNum, int nextPostionNum) {
this.lineNum = lineNum;
this.columnNum = columnNum;
this.nextPostionNum = nextPostionNum;
}
public int getLineNum() {
return lineNum;
}
public void setLineNum(int lineNum) {
this.lineNum = lineNum;
}
public int getColumnNum() {
return columnNum;
}
public void setColumnNum(int columnNum) {
this.columnNum = columnNum;
}
public int getNextPostionNum() {
return nextPostionNum;
}
public void setNextPostionNum(int nextPostionNum) {
this.nextPostionNum = nextPostionNum;
}
@Override
public String toString() {
return "Position{" +
"lineNum=" + lineNum +
", columnNum=" + columnNum +
", nextPostionNum=" + nextPostionNum +
'}';
}
}
第三步:抽象一个栈,用以存放探索过的可以走的位置;
//请使用 LinkedList 模拟一个堆栈或队列的数据结构?
//双向链表实现
public class Stack {
private LinkedList link;
//该栈具有自动扩容的能力
public Stack() {
link = new LinkedList();
}
//入栈
public void push(Object obj) {
link.addLast(obj);
}
//出栈
public Object pop() {
//队列
//return link.removeFirst();
// 堆栈
return link.removeLast();
}
//取出栈底的元素,这违背了栈的原则---先进后出
public Object orderPop() {
return link.pollFirst();
}
//判断栈空
public boolean isEmpty() {
return link.isEmpty();
}
//初始化栈
public void InitStack() {
link.clear();
}
//返回栈中元素的个数
public int getSize() {
return link.size();
}
//获取栈顶元素,但是不出栈
public Object topObject() {
return link.getLast();
}
}
第四步:算法实现;
//传递入口和出口
static void mgPath() {
int line = 0, column = 0, nextPotion = -1, find = 0, k;
//迷宫求解问题
//定义一个二维数组,代表迷宫
int[][] maze = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 1, 1, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 1, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 0, 1, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 1, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 0, 1, 1},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
Stack stack = new Stack();
stack.InitStack();
//入口
Position entry = new Position(1, 1, -1);
maze[1][1] = -1;
stack.push(entry); //将入口压入栈中
while (!stack.isEmpty()) {
//读取栈顶元素,然后判断是不是出口
Position top1 = (Position) stack.topObject();
//找到路径,判断是不是出口
if (top1.getLineNum() == 8 && top1.getColumnNum() == 8) {
System.out.println("迷宫路径如下: " + "\n");
System.out.println("栈内元素个数: " + stack.getSize());
int max = stack.getSize();
for (k = 0; k < max; k++) {
//栈逆转成队列
Position out = (Position) stack.pop();
System.out.println("(" + out.getLineNum() + " , " + out.getColumnNum() + "); ");
if ((k + 1) % 5 == 0) { //每行5个元素,然后换行
System.out.println("\n");
}
}
System.out.println("\n");
return;
}
while (nextPotion < 4 && find == 0) {
nextPotion++;
Position top = (Position) stack.topObject();
switch (nextPotion) {
case 0:
line = top.getLineNum() - 1;
column = top.getColumnNum();
break;
case 1:
line = top.getLineNum();
column = top.getColumnNum() + 1;
break;
case 2:
line = top.getLineNum() + 1;
column = top.getColumnNum();
break;
case 3:
line = top.getLineNum();
column = top.getColumnNum() - 1;
break;
}
if (maze[line][column] == 0) {
find = 1;
}
//何时将nextPotion 再次设置成-1 ?
}
if (find == 1) {
Position aPosition = new Position(line, column, -1);
//System.out.println("入栈的位置记录: x =" + aPosition.getLineNum() + " ,y= " + aPosition.getColumnNum() );
stack.push(aPosition);
maze[line][column] = -1;
find = 0;
nextPotion = -1;
//System.out.println("已经入栈的位置: " +maze[line][column] );
}
if(nextPotion == 4 && find == 0 ) {
nextPotion =-1;
//否则将栈顶元素弹出,修改对应位置的值回到0
Position topElemnet = (Position) stack.topObject();
maze[topElemnet.getLineNum()][topElemnet.getColumnNum()] = 0;
//System.out.println("退站的位置:" + topElemnet.getLineNum() + " ,y= " + topElemnet.getColumnNum());
stack.pop();
}
}
System.out.println("没有可走的路径!");
}
结果:
迷宫路径如下:
栈内元素个数: 15
(8 , 8);
(8 , 7);
(7 , 7);
(7 , 6);
(6 , 6);
(6 , 5);
(5 , 5);
(5 , 4);
(4 , 4);
(4 , 3);
(3 , 3);
(3 , 2);
(2 , 2);
(2 , 1);
(1 , 1);