前言
大家还记得当初C语言我们一起学习的递归吗?说好的要实现老鼠走迷宫和八皇后问题!他来了!!!
老鼠走迷宫
MiGong.java
public class MiGong {
// 编写一个main方法
public static void main(String[] args) {
//思路
//1. 先创建迷宫,用二维数组表示 int[][] map = new int[8][7];
//2. 先规定 map 数组的元素值: 0 表示可以走的路 1 表示障碍物
int[][] map = new int[8][7];
//3. 将最上面的一行和最下面的一行,全部设置为1
for (int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
//4. 将最右面的一行和最左面的一行,全部设置为1
for (int i = 0; i < 8; i++) {
map[i][0] = 1;
map[i][6] = 1;
}
map[3][1] = 1;
map[3][2] = 1;
//输出当前的迷宫
System.out.println("===========当前地图情况===========");
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");//输出一行
}
System.out.println();
}
//使用findWay给老鼠找路
T t1 = new T();
t1.findWay(map,1,1);
System.out.println("===========找路的情况如下===========");
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");//输出一行
}
System.out.println();
}
}
}
class T {
//使用递归回溯的思想来解决老鼠出迷宫
//1. findWay方法就是专门来找出迷宫的路径
//2. 如果找到,就返回true,否则返回false
//3. map就是二维数组,即表示迷宫
//4. i,j就是老鼠的位置,初始化的位置为(1,1)
//5. 因为我们是递归的找路 ,所以我们先规定 map数组各个值的含义
// 0 表示可以走 1 表示障碍物 2 表示可以走 3 表示走过,但是走不通是死路
//6. 当map[6][5] = 2 就说明找到通路了,就可以结束,否则就继续找。
//7. 先确定老鼠找路的策略 下->右->上->左
public boolean findWay(int[][] map, int i, int j) {
if (map[6][5] == 2) {//说明已经找到
return true;
} else {
if (map[i][j] == 0) {//当前这个位置为0,说明表示可以走
//我们假定可以走通
map[i][j] = 2;
//使用找路策略,来确定该位置是否真的可以走通
if (findWay(map, i + 1, j)) {//先走下
return true;
} else if (findWay(map, i, j + 1)) {//右
return true;
} else if (findWay(map, i - 1, j)) {//上
return true;
} else if (findWay(map, i, j - 1)) { //左
return true;
} else {
map[i][j] = 3;
return false;
}
} else {//map[i][j] = 1, 2, 3
return false;
}
}
}
}
八皇后问题
1.问题分析
八皇后问题是一个古老而著名的问题,是回溯算法和递归调用的典型案例。八皇后难题是要将八个皇后(Queen)放在棋盘上,任何两个皇后都不能互相攻击(即没有任意两个皇后是在同一行、同一列或者同一条对角线上),问一共有多少种摆法?
2.步骤分析
- 第一个皇后先放在第一行第一列
- 第二个皇后放在第二行第一列,然后判断能否在该位置放皇后,如果不可以,则继续放下一列,直至找到一个合适的位置
- 继续放置第三个皇后,还是第一列、第二列…直到第8个皇后也能放在一个不能相互攻击的位置,就找到了一个正确解。
- 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯。即将第一个皇后放在第一列的所有解逐个得到。
- 完成以上步骤之后,将第一个皇后放在第二列,后面循环执行1, 2, 3, 4 步骤。
Queen.java
class B {
//定义横竖斜方向上是否有棋子
public static boolean flag = true;
//检查棋盘
public int checBoard(int MAXQUEEN, int row, int col, int[][] Board){
//行方向上
for (int i = 0; i < MAXQUEEN; i++) {
if (Board[row][i] == 1) {
return 0;
}
}
//列方向上
for (int i = 0; i < MAXQUEEN; i++) {
if (Board[i][col] == 1) {
return 0;
}
}
//右下方向上
for (int i = row, j = col; i < MAXQUEEN && j < MAXQUEEN; i++, j++) {
if (Board[i][j] == 1) {
return 0;
}
}
//左上方向上
for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
if (Board[i][j] == 1) {
return 0;
}
}
//右上方向上
for (int i = row, j = col; i >= 0 && j < MAXQUEEN ; i--, j++) {
if (Board[i][j] == 1) {
return 0;
}
}
//左下方向上
for (int i = row, j = col; i < MAXQUEEN && j >= 0 ; i++, j--) {
if (Board[i][j] == 1) {
return 0;
}
}
if (flag) {
//此点符合要求,可以下
Board[row][col] = 1;
//如果已经到最后一行,则打印棋盘
if (row == MAXQUEEN - 1) {
printBoard(MAXQUEEN, Board);
}
return 1;
}
return 0;
}
//打印棋盘
public static void printBoard(int MAXQUEEN, int[][] Board) {
for (int i = 0; i < MAXQUEEN; i++) {
for (int j = 0; j < MAXQUEEN; j++) {
System.out.print(Board[i][j] + " ");
}
System.out.println();
}
System.out.println("===================");
}
}
public class Queen {
public static int MAXQUEEN = 8; //皇后个数,也是棋盘行列数
public static int[][] Board = new int[MAXQUEEN][MAXQUEEN]; //初始化棋盘
private static int count;
//测试方法
public static void startTest(B b, int row) {
//第0列开始
for (int col = 0; col < MAXQUEEN; col++) {
//检查位置是否可以放棋子
if (b.checBoard(MAXQUEEN, row, col, Board) == 1) {
if (row == MAXQUEEN - 1) {
count++;
}
//递归,向下一行前进
if (row < MAXQUEEN - 1) {
startTest(b,++row);
//回退上一个栈
--row;
}
}
//重新赋值为0,进行下一次判断
Board[row][col] = 0;
}
}
//编写一个main方法
public static void main(String[] args) {
int row = 0;
B b1 = new B();
startTest(b1,row);
System.out.println("摆放一共有" + count + "种");
}
}