迷宫求解(循环,java)

`
哇!!!!!先让我哭一场!!!
看了一天的迷宫求解算法,终于有点看懂了。
啥都不说了,上代码,代码的注释自我感觉还行,比较详细。

//栈的节点的类
class stack {
	private int x = 0;//横纵坐标
	private int y = 0;
	private stack next = null;//尾指针
	private int front = 0;
	//front用于记录走过了几个方向,1 代表走过一个方向,2 代表走过两个......
	stack(int x, int y){
		this.x = x;
		this.y = y;
	}
	void setFront(int i) {
		front = i;
	}
	int getFront() {
		return front;
	}
	int getX() {
		return x;
	}
	int getY() {
		return y;
	}
	void setNext(stack next) {
		this.next = next;
	}
	stack getNext() {
		return next;
	}
	void print() {//打印坐标
		System.out.printf("(%d, %d), ",x, y);
	}
}
public class maze {
	//对一些数值进行初始化
	static int row = 0;
	static int col = 0;
	static int x = 0;
	static int y = 0;
	//栈底
	static stack head = new stack(0,0);
	static stack now = null;
	static stack top = head;
	//初始化迷宫
	static int[][] map = {{1,1,1,1,1,1,1,1,1,1},//0
			   {1,0,0,1,0,0,0,1,0,1},//1
			   {1,0,0,1,0,0,0,1,0,1},//2
			   {1,0,0,0,0,1,1,0,0,1},//3
			   {1,0,1,1,1,0,0,0,0,1},//4
			   {1,0,0,0,1,0,0,0,0,1},//5
			   {1,0,1,0,0,0,1,0,0,1},//6
			   {1,0,1,1,1,0,1,1,0,1},//7
			   {1,1,0,0,0,0,0,0,2,1},//8
			   {1,1,1,1,1,1,1,1,1,1},//9
	};
	
	static boolean[][] isBy = new boolean[10][10];//设置标记位
	
	public static void main(String[] da) {
		//初始化标记
		for(int i = 0; i < 9; i++)
			for(int j = 0; j < 9; j++)
			    isBy[i][j] = false;//将标记位全部初始化为未走过
		
		boolean result = search(1,1);//寻找路径
		System.out.println(result);
	}
	public static boolean search(int x, int y) {
		stack temp = null;//定义一个节点
		do {
			if (map[x][y] != 1 && !isBy[x][y]) {//如果当前位置不是墙且没走过
				isBy[x][y] = true;//将当前位置置为走过
				temp = new stack(x, y);
				push(head, temp);//入栈
				if( map[x][y] == 2) {//如果到了终点,打印地图,返回true
					printRoad(head);
					return true;
				}
				y += 1;//默认从左向右走
				temp.setFront(temp.getFront()+1);//将方向设置为1,表示已经从左向右走过
			}
			else {//如果位置是墙或者是走过的坐标
				while(top.getFront() == 4 && !isEmpty()) {//上一步的坐标,如果四个方向都走过且都不通,则出将上一步栈
					pop(head);
				}
				if(top.getFront() < 4) {//上一步坐标,四个方向中有没有走过的方向,则换个方向继续探寻
					//此坐标不通,将x, y重置为上一步的坐标
					x = top.getX();
					y = top.getY();
					switch(top.getFront()) {
					case 1: x += 1;break;//向下走
					case 2: y -= 1;break;//向左走
					case 3: x -= 1;break;//向上走
					default:;
					}
					top.setFront(top.getFront() + 1);//将front + 1表示又试探了一个方向
				}
			}
		} while(!isEmpty());
		return false;
	}
	static boolean isEmpty() {//判断栈是否为空
		if(head.getNext() == null)return true;
		else return false;
	}
	static void printRoad(stack in) {//循环打印路径
		while(in!=null) {
			in.print();
			in = in.getNext();
		}
	}
	static void push(stack in, stack now) {//入栈
		while(in.getNext()!=null)
			in = in.getNext();
		in.setNext(now);
		top = now;
	}
	static void pop(stack in) {//出栈
		stack front = in.getNext();
		while(front.getNext()!=null) {
			in = front;
			front = front.getNext();
		}
		in.setNext(null);
		top = in;
	}
}

之前用递归做了一遍,然后改用循环做时各种不适应。
但是我发现循环找到结果后比递归更好跳出。同时也感觉算法更加清爽。
之前一直对循环里的front这个变量不理解。后来发现是用于记录试探过几个方向的。递归里的front表示这个坐标是从哪个坐标过来的,(1表示从左边坐标走过来,2表示从上边坐标走过来…)我刚开始以为两个front是一样的,后面才发现循环中的front表示的是这个节点去过哪几个方向。1表示向右试探过,2表示向右和下试探过,3表示向右,下和左试探过,4表示四个方向都试探过。理解了这个,其实循环求路径就不是很难了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值