递归解决八皇后问题 Java语言

      八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

在这里,我们将会使用二维数组和递归的方法来解决这个复杂的问题。

    第一种方法是通过复制最开始的棋盘arr(开始的棋盘是一个二维数组,当然初始化的时候里面默认都为零,我们用1来表示存在皇后)到newarr,然后在newarr棋盘上放置皇后。我们先从第一行的第一列开始存放皇后

递归解决八皇后问题 Java语言_第1张图片

      接下来,我们判断第二个皇后存放在第二行的第危险,这样会发现正上方以经存在了皇后,所以我们继续判断第二行的第二列是否危险,这样又会发现在对角线的左上方还是存在皇后,我们会继续执行上次的操作,将继续判断第二行的第三列,直到在第二行存放的皇后没有“危险”,然后将皇后放入棋盘对应的位置;当第二行也存放好了,接下来就执行eightqueen(newarr,row+1)函数,即程序走向下一行继续判断然后继续放入皇后,如果按照这种操作一直执行到最后一行,并且最后一行中都不可以存放皇后时,我们就要进行回溯

递归解决八皇后问题 Java语言_第2张图片(最后一行是“危险的”)

       此时,我们需要做的就是回溯到上一层,然后将上一层存放的皇后拿掉,接着在上一层再找到存放的合适的位置,如果在上一层还是没有找到,那么就将继续回溯,直到满足条件为止。

递归解决八皇后问题 Java语言_第3张图片

上面的图是从第二张图开始回溯得来的,在当前的情况下都没有任何危险,然后就可以接着向下递归了,如果到后面继续存在之前的情况,那我们就进行回溯,然后再递归,直到有一种结果出来为止。

class EightQueen{
    public static int count = 0;    //创建计数器
    public static int[][] arr = new int[8][8];    //创建开始的棋盘数组
    
    public static void main(String[] args){
        eightqueen(arr,0);    //开始执行递归程序
    }

    public static void eightqueen(int[][] arr,int row){    //将原来的数组和刚开始的行数传进来
        int[][] newarr = new int[8][8];    //创建一个新的8*8的数组
        for(int i=0;i=0;i--){
            if(newarr[i][j]==1){
                return false;
            }
        }
        for(int x=row-1,y=j-1;x>=0&&y>=0;x--,y--){
            if(newarr[x][y]==1){
                return false;
            }
        }
        for(int x=row-1,y=j+1;x>=0&&y

上述是第一种方法,下面是第二种方法,通过一个二维数组来解决问题,其实两者使用的方法都一样,都是递归和回溯。

class EightQueen1{
    public static int[][] arr = new int[8][8];
    public static int count = 0;
    public static void main(String[] args){
        eightqueen(0);
    }
    public static void show(){    //在打印结果的时候只打印8*8的范围就可以了
        System.out.println("第"+count+"次结果:");
        for(int i=0;i=0;i--){
            if(arr[i][col]==1){
                return false;
            }
        }
        for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
            if(arr[i][j]==1){
                return false;
            }
        }
        for(int i=row-1,j=col+1;i>=0&&j

上面的两个方法其实思路都是一样的,在判断危险这个函数中,我们其实可以运用更为简单的方法,利用绝对值来进行简化代码。

你可能感兴趣的:(数据结构与算法)