Java编写八皇后问题
public class Recursion {
// 皇后的数量
private int maxSize = 8;
private int[] arr = new int[maxSize];
// 解法的数量
private static int count = 0;
public static void main(String[] args) {
Recursion queue8 = new Recursion();
queue8.check(0);
System.out.println("count : " + count);
}
// 放置皇后
private void check(int n){
if(n == maxSize){ // n=8, 说明8个皇后已经放好, 因为7个索引等于maxSize, 再传进来n+1就不会继续执行
printArr();
return;
}
for (int i = 0; i < maxSize; i++) {
// 先把 第n个皇后放到 0 列, 并检查,不行就放在i++列
arr[n] = i;
if(judge(n)){ // 如果冲突, 则会停止以下代码。就会将当前的皇后放到下一个位置,i++的位置
check(n+1); // 判断没问题,则可以继续放置下一个,n+1个,
// 但是,如果进入方法,原先的for并没有执行完,而是被压在方法栈下面,继续n+1方法
// 如果n+1执行完了,则调回到for,或者叫回溯的地方,继续执行for循环,
// ,如果有问题,则,不会进入这里, 则是放置到下一列i++列。
// 所以回溯就是方法栈的回溯,栈顶的方法执行完了, 弹出栈,继续执行下面的栈方法,这就叫方法回溯
}
}
}
// 当我们放置第n个皇后的时候, 就去检测该皇后是否和前面已经摆放好的皇后冲突
/**
*
* @param n 表示第n个皇后
* @return false表示冲突, true表示不冲突
*/
// 每次放置一个皇后,都要进行从第一列,索引为0的循环遍历,进行判断
private boolean judge(int n){ // 第一次n为0, 不用和其他的列比, 则直接返回true, 因为i<n为false,停止循环
for (int i = 0; i < n; i++) {
// Math.abs(n-i) == Math.abs(arr[n] - arr[i]) 判断是否在同一斜线
// Math.abs(n-i) 表示行的差值, Math.abs(arr[n] - arr[i]) 表示列的差值
// 如果行 == 列, 这说明在同一斜线
if(arr[i] == arr[n] || Math.abs(n-i) == Math.abs(arr[n] - arr[i])){
// System.out.println("arr[i] --> " + arr[0] + " , arr[n] --> " + arr[n] + " === " + (arr[0] == arr[n]));
return false; // return false后不会再继续未完成的for了
}
}
return true;
}
// 将皇后的摆放的位置打印
private void printArr(){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
Recursion.count++;
}
}