package demo05_recursion;
/**
* @program: dataStructures_algorithms
* @description: 八皇后问题
* @author: Sun
* @create: 2020/01/10 14:16
* @version: 1.0
*/
public class Queen8 {
private int max = 8;
private int[] arr = new int[max];
private static int COUNT = 0;
/**
* @Description: 判断皇后放置位置是否正确
* @param n: 放入的第几个皇后,从0开始计数
* @return boolean: 如果位置不满足要求,返回false,如果满足要求则返回true
* @throws
*/
public boolean judge(int n){
for (int i = 0; i < n; i++) {
if (arr[i] == arr[n] || Math.abs(n - i) == Math.abs(arr[n] - arr[i])){
return false;
}
}
return true;
}
/**
* @Description: 打印结果
* @return void
*/
public void print(){
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
/**
* @Description: 摆放皇后
* @param n: 检查第n个皇后
* @return void
*/
public void check(int n){
// 如果 n = 8 则说明摆放在第八行的皇后的位置是正确的,因为皇后摆放
// 行数时从0开始,当执行check(8)的时候,就说明了第八行皇后位置没问
// 题,但我们没有检查第9行的需求,所以当 n = 8 的时候我们打印皇后摆
// 放位置的信息
if ( n == 8){
COUNT++;
print();
return;
}
for (int i = 0; i < max; i++) {
arr[n] = i; // 记录当前皇后所在列位置
if (judge(n)){
// 每次递归的时候都会在本行进行依次for循环检查,这里检查的是皇后
// 在每一列的位置是否满足要求:
// >如果满足要求就继续摆放下一行的皇后,并再次进行循环检查摆放的列位置是否
// 满足要求(继续重复此次满足和不满足的逻辑)
// >如果不满足要求,回溯就产生了,因为这时候本行的for循环已经运行完毕,
// 发现没有一个位置符合要求,那么就会回溯到上一行(上一个方法栈中)
// 的for循环中,这时候上一行的皇后位置会向后移动一列(相当于出了
// for循环后再次执行 arr[n] = i ),然后再接着放下一行皇后,同样会
// 在for循环中从第一列开始检查位置是否满足要求,并再次重复满足和不
// 满足的逻辑。
check(n + 1); // 开始递归
// 这里的回溯机制主要是在于会去纠正之前几行已经放好的皇后的位置,在每次
// 递归执行的时候,只要一行检查完毕没有一个位置满足皇后摆放要求,就会去
// 纠正上一行的位置,通过不断的回溯就会纠正之前每一行的位置,直到第一行的
// 所有列都循环完毕,就把皇后所有可能摆放的位置都检查了一遍,所以这个递归
// 的效率相对来说是很低的
}
}
}
public static void main(String[] args) {
Queen8 q = new Queen8();
q.check(0);
System.out.println(Queen8.COUNT);
}
}
八皇后问题递归解决方案
最新推荐文章于 2022-09-14 23:23:07 发布