数据结构和算法之回溯递归“八皇后问题”

33 篇文章 0 订阅
32 篇文章 0 订阅

八皇后问题:

要求:
要求皇后不能再同一行,不能在同一列,也不能在同一个斜线上面
思路:

1:先要构造八皇后的棋盘:表示皇后应该摆放的位置;这个可以用一位数组进行表示:下标表示的是放在棋盘的第几行,数组中的值表示放在棋盘中的第几列
2:思路:
(1):第一个皇后放在棋盘的第一行第一列
(2):第二个皇后放在第二行第一列,然后判断是否OK,如果不OK,继续放在第二行第二列,第三列,依次将所有列放完,直到找到一个合适的。
(3):继续第三个皇后,还是第一列,第二列直到八个皇后放在一个不冲突的位置上,算是找到了一个解
(4):当得到一个正确解之后,在栈回退到上一个栈的时候,就会开始回溯,即将第一个皇后,放在第一列的所有正确解,全部得到
(5):然后回头的时候第一个皇后放在第一行的第二列,后面继续1,2,3,4的步骤即可

代码如下所示:

public class EightProcess {
    //定义一个max表示一共有多少个皇后
    int max=8;
    //定义一个数组arr保存皇后防止位置的保存结果,比如arr[8]={0,4,7,5,2,6,1,3}
    int[]arr=new int[max];//因为棋盘是共享的所以写在外面
    static int count=0;
    static int judgeCount=0;

    public static void main(String[] args) {
        //测试:
        EightProcess queue8=new EightProcess();
        queue8.check(0);
        System.out.println("一共有"+count+"解法");
        System.out.println("一共判断了"+judgeCount+"次");
    }

    //编写一个方法放置第n个皇后
    //注意:check每次递归的时候,进入该方法都会有for循环,执行完了才会退出,因此会有回溯
    private void check(int n){
        if(n==max){
            //1:也就是说在n=8的时候,其实八个皇后已经放好了
            print();
            return;
        }
        //2:否则就是前面的8个皇后开始放置,判断是否冲突
        for (int i = 0; i <max ; i++) {
            //2.1:先把当前的皇后放在改行的第一列,判断是否冲突即可
            arr[n]=i;
            //2.2:并且判断是否发生冲突
            if(judge(n)){//在这里默认结果是不冲突
                //2.3:接着放n+1个皇后,即开始递归
                check(n+1);//对于8个皇后,在同一层都会有8次循环
            }
            //一旦发生冲突,就继续执行arr[n]=i;也就是放入第二列,第三列等等
        }
    }

    //当我们防止第n个的皇后的时候就去检测是否与前面已经摆放的皇后发生冲突
    private boolean judge(int n){
        judgeCount++;
        /*说明:
         * 1:arr[i]==arr[n]表示判断第n个皇后是否与前面的n-1个皇后在同一列:因为下标代表的数组里面的值
         * 2:表示在同一列,同一斜线,Math.abs(int a)是一个算法,是绝对值
         * 3:为什么没有说行数的关系,因为n就是代表的行数,是递增的,放了第一个,就会立马往第二行开始放*/
        //n表示放置第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;//表示当前的皇后与前面的皇后的位置是不会发生冲突的
    }

    //写一个方法,可以将皇后最后摆放的位置打印出来:也就是将那个数组打印出来即可
    private void print(){
        count++;
        for (int i = 0; i <arr.length ; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }
}

运行结果如下所示:
在这里插入图片描述

分析:
递归回溯解决八皇后问题的方法很简单,但是效率低下。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值