java之递归解决八皇后问题

八皇后问题


文章内容选自尚硅谷,jdk8,eclipse环境

问题剖析

  1. 解决八皇后问题需要创立一个8×8的棋盘,但是这儿可以用一个有八个元素的一维数组来解决
  2. 数组的标号代表着行,数组每个元素的值代表着对应的列。
  3. 解决该问题的思路有,首先得设立一个判断列是否冲突的函数judge(int n),该函数的形参为传入的行数,即判断前几行与该行的值(该值即为列的位置)是否冲突。
  4. 然后还有一个递归的函数check(int n),形参依然为行数。该函数用于进行递归,里面有一个for循环,把judge(int n)函数置于for循环内,这一点是实现八皇后问题的关键步骤。
  5. 在check(int n)的for循环内不断执行judge(int n)函数,如果能通过,进行递归,即check(n+1),如果判断不通过,执行for循环,更改当前行所存的列数,然后继续执行判断。
  6. 由此可见,如果check(int n)内的for循环内的judge(int n)一直无法判断为true,直到for循环结束的时候,将会回溯到上一个check(int n),更改上一个check(int n)当前行的值(列的位置),继续进行judge(int n)的判断。

总结为一点,在某一行上,要么进行递归,进入下一行,要么进行回溯(即8个列值都不行),进入递归函数的上一级,改变上一行所在的列(上一行的列值+1)。

在这里插入图片描述
上图选自尚硅谷

示例代码

package recursion;

public class Queue8 {
	int max = 8;
	int[] chessBoard = new int[max];
	int count;
	int judgeCount;
	public static void main(String[] args) {
		Queue8 test = new Queue8();
		test.check(0);
		System.out.printf("输出共有%d解法",test.count);
	}
	
	private void check(int n){
		if(n == max){
			print();
			return;
		}
		for(int i = 0;i < max;i++){
			chessBoard[n] = i; //确定第n行所摆放的列的位置
			if(judge(n)){
				check(n+1);
			}
		}
	}
	
	private boolean judge(int n){
		judgeCount++;
		for(int i = 0;i < n;i++){ //仅判断前n-1行所摆放的列与第n行所摆放的列是否相冲突
			if(chessBoard[n] == chessBoard[i] || Math.abs(n-i) == Math.abs(chessBoard[n]-chessBoard[i]))
				return false;
				
		}
		return true;
	}

	private void print(){
		count++;
		for(int i = 0;i < max;i++){
			System.out.printf(chessBoard[i] + " ");
		}
		System.out.println();
	}
}

运行结果为

0 4 7 5 2 6 1 3
0 5 7 2 6 3 1 4
0 6 3 5 7 1 4 2
0 6 4 7 1 3 5 2
1 3 5 7 2 0 6 4
1 4 6 0 2 7 5 3
1 4 6 3 0 7 5 2
1 5 0 6 3 7 2 4
1 5 7 2 0 3 6 4
1 6 2 5 7 4 0 3
1 6 4 7 0 3 5 2
1 7 5 0 2 4 6 3
2 0 6 4 7 1 3 5
2 4 1 7 0 6 3 5
2 4 1 7 5 3 6 0
2 4 6 0 3 1 7 5
2 4 7 3 0 6 1 5
2 5 1 4 7 0 6 3
2 5 1 6 0 3 7 4
2 5 1 6 4 0 7 3
2 5 3 0 7 4 6 1
2 5 3 1 7 4 6 0
2 5 7 0 3 6 4 1
2 5 7 0 4 6 1 3
2 5 7 1 3 0 6 4
2 6 1 7 4 0 3 5
2 6 1 7 5 3 0 4
2 7 3 6 0 5 1 4
3 0 4 7 1 6 2 5
3 0 4 7 5 2 6 1
3 1 4 7 5 0 2 6
3 1 6 2 5 7 0 4
3 1 6 2 5 7 4 0
3 1 6 4 0 7 5 2
3 1 7 4 6 0 2 5
3 1 7 5 0 2 4 6
3 5 0 4 1 7 2 6
3 5 7 1 6 0 2 4
3 5 7 2 0 6 4 1
3 6 0 7 4 1 5 2
3 6 2 7 1 4 0 5
3 6 4 1 5 0 2 7
3 6 4 2 0 5 7 1
3 7 0 2 5 1 6 4
3 7 0 4 6 1 5 2
3 7 4 2 0 6 1 5
4 0 3 5 7 1 6 2
4 0 7 3 1 6 2 5
4 0 7 5 2 6 1 3
4 1 3 5 7 2 0 6
4 1 3 6 2 7 5 0
4 1 5 0 6 3 7 2
4 1 7 0 3 6 2 5
4 2 0 5 7 1 3 6
4 2 0 6 1 7 5 3
4 2 7 3 6 0 5 1
4 6 0 2 7 5 3 1
4 6 0 3 1 7 5 2
4 6 1 3 7 0 2 5
4 6 1 5 2 0 3 7
4 6 1 5 2 0 7 3
4 6 3 0 2 7 5 1
4 7 3 0 2 5 1 6
4 7 3 0 6 1 5 2
5 0 4 1 7 2 6 3
5 1 6 0 2 4 7 3
5 1 6 0 3 7 4 2
5 2 0 6 4 7 1 3
5 2 0 7 3 1 6 4
5 2 0 7 4 1 3 6
5 2 4 6 0 3 1 7
5 2 4 7 0 3 1 6
5 2 6 1 3 7 0 4
5 2 6 1 7 4 0 3
5 2 6 3 0 7 1 4
5 3 0 4 7 1 6 2
5 3 1 7 4 6 0 2
5 3 6 0 2 4 1 7
5 3 6 0 7 1 4 2
5 7 1 3 0 6 4 2
6 0 2 7 5 3 1 4
6 1 3 0 7 4 2 5
6 1 5 2 0 3 7 4
6 2 0 5 7 4 1 3
6 2 7 1 4 0 5 3
6 3 1 4 7 0 2 5
6 3 1 7 5 0 2 4
6 4 2 0 5 7 1 3
7 1 3 0 6 4 2 5
7 1 4 2 0 6 3 5
7 2 0 5 1 4 6 3
7 3 0 2 5 1 6 4
输出共有92解法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值