八皇后问题(递归)

八皇后问题介绍

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.在8x8格的国际象棋上摆放8个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行,同一列或同一斜线上,问有多少中摆法(92)

八皇后问题算法思路分析

  1. 第一个皇后先放第一行第一列
  2. 第二个皇后放在第二行第一列,然后判断是否OK,如果不OK,继续放在第二列,第三列,依次把所有列都放完,找到一个合适的
  3. 继续放第3个皇后,还是第一列,第二列.......知道第8个皇后也能放在一个不冲突的位置,算是找到了一个正确的解
  4. 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到.
  5. 然后回头继续第一个皇后放到第二列,后面继续循环执行1,2,3,4的步骤
  6. 示意图:

说明

  • 理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过一个算法,用一个一维数组即可解决问题.arr[8] = {1,4,7,5,2,6,1,3}
  • 对应arr下标,表示第几行,即第几个皇后,arr[i] = val,val表示第i+1个皇后,放在第i+1行的val+1列.

代码实现

public class queue8 {
    //定义一个max表示多少个皇后
    int max = 8;
    //定义一个数组,保存皇后放置位置的结果,比如arr={1,4,7,5,2,6,1,3}
    int[] arr = new int[max];
    static  int count = 0;
    public static void main(String[] args) {
        queue8 que = new queue8();
        que.check(0);
        System.out.println("总共有:"+ count);

    }

    /**
     * 放置第n+1个皇后
     *
     * @param n 皇后的下标
     */
    public void check(int n) {
        //结束递归的条件,n=8,表示0到7下标的皇后已经放置成功,即8个皇后都放置成功了
        if (n == 8) {
            print();  //打印放置结果
            return;
        }
        for (int i = 0; i < max; i++) {
            //把下标为n的皇后依次放在第1到8列的位置进行判断是否冲突
            arr[n] = i;
            if (judge(n)) { //不冲突
                check(n+1); // 判断下一个
            }
        }
    }

    /**
     * @param n 皇后的下标
     * @return 不冲突返回true
     */
    private boolean judge(int n) {
        //判断冲突就是判断是否同列或者同斜线上
        for (int i = 0; i < n; i++) {
            //arr[i] == arr[n] 是否在同一行
            //Math.abs(arr[n] - arr[i]) == Math.abs(n - i)是否在同同一斜线
            if (arr[i] == arr[n] || Math.abs(arr[n] - arr[i]) == Math.abs(n - i)){
                return false;
            }
        }
        return true;
    }

    //打印放置的结果
    private void print() {
        count++;
        for (int i : arr) {
            System.out.print(i + " ");
        }
        System.out.println();
    }
}

原文地址:https://www.cnblogs.com/liuzhidao/p/13804740.html