递归回溯之八皇后问题详解

Posted mx_info

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归回溯之八皇后问题详解相关的知识,希望对你有一定的参考价值。

递归回溯之八皇后问题详解

说明

  1. 八皇后问题是指在 8 * 8的国际象棋棋盘上每一行放置一个皇后,要保证每一行每一列不能有重复,并且对角线也不能有重复,问总共有多少种摆法
  2. 可以使用 回溯 + 递归 的思路
  3. 每一个皇后的摆放每次都遍历 每一行的这八个位置,判断每一个位置是否可以摆一个皇后
  4. 如果可以摆放,则再循环判断下一行的八个位置是否可以摆放,直到摆完8个皇后,
  5. 然后从栈顶开始递归,如果不加其他优化算法,时间复杂度理论上为 n ^ 8
  6. 因为每一个check方法都要循环判断8次,而每次判断完可以摆放后又调用一个check方法,总共有8个皇后
  7. 详解见下源码

源码及分析

package algorithm.recursion;

/**
 * @author AIMX_INFO
 * @version 1.0
 */
public class Queue8 {
    //定义max保存皇后的个数
    static int max = 8;
    //定义一维数组arr 保存皇后所在的位置,数组下标+1表示所在行,对应的值为所在的列
    static int[] arr = new int[max];
    public static void main(String[] args) {
        //从第一个皇后开始放置
        check(0);
    }
    //编写一个方法,放置第n个皇后
    public static void check(int n){
        if (n == max){
            print();
            return;
        }
        //依次放入皇后,并判断是否冲突
        for (int i = 0; i < max; i++) {
            //把当前这个皇后先放置到第一列
            arr[n] = i;
            //判断放置第n个皇后到第i列时是否冲突,如果不冲突,则放置下一个皇后
            if (judge(n)){
                check(n + 1);
            }
            //如果冲突,则将这个皇后放置到下一列
        }
    }
    //编写方法判断第n个皇后和前边的皇后是否冲突
    public static boolean judge(int n){
        //遍历前n个皇后并判断
        for (int i = 0; i < n; i++) {
            //arr[i] == arr[n]判断是否在同一列
            //Math.abs(n - 1) == Math.abs(arr[n] - arr[i])判断是否在对角线上
            if (arr[i] == arr[n] || Math.abs(n - i) == Math.abs(arr[n] - arr[i])){
                return false;
            }
        }
        return true;
    }

    //编写方法显示合适的位置
    public static void print(){
        for (int i = 0; i < max; i++) {
            System.out.print(arr[i]+"  ");
        }
        System.out.println();
    }
}

以上是关于递归回溯之八皇后问题详解的主要内容,如果未能解决你的问题,请参考以下文章

回溯算法之八皇后问题

八皇后问题算法详解

JavaScript之八皇后问题(归纳)

回溯法八皇后问题(递归和非递归)

八皇后,回溯与递归(Python实现)

递归和回溯求解8皇后问题