Java数据结构-八皇后问题

🚗前言:

 

        八皇后问题是经典的算法问题,其独特的游戏玩法总是令人绞尽脑汁的同时又津津乐道,但是在我们写代码的时候又觉得,八皇后问题无从下手,对此可爱的博主根据自己学到的知识写了这篇博客,让大家跟随着作者的脚步,一同学会八皇后问题的真确解

        咱们从一下的方面展开阐述:

八皇后问题的定义 ➡️ 八皇后问题的思路 ➡️ 八皇后问题的代码实现与代码分析 ➡️ 结论

        如果喜欢本博客戳这关注作者😘吧!

 

        ↘️往期精彩:

                约瑟夫问题的实现


🚓八皇后问题概述:

        在一个8*8的棋盘中(有点类似于国际象棋那种黑白棋盘),放置皇后,放置皇后的时候必须遵守以下规则

  1. 放置的皇后不能在同一行,同一列,同一斜线
  2. 皇后必须从第一行开始放起
  3. 如皇后能放到最后一行则表示游戏成功

        看到这,相信小伙伴都觉得 ,且继续往下看


 🦽八皇后问题的思路:

 传统思路:

  • 创建一个二维数组
  • 一个一个去放,并判断是否在同一直线,同一列,同一斜线,如果是就放,不是就改
  • 循环到最后得出结果

 回溯思路:

  • 创建一个一维数组并指定其容量(一维数组应该是个静态引用)
  • 创建一个判断方法
  • 利用递归迭代完成代码
1.在第一行第一列放一个皇后
2.在第二行第一列放一个皇后,判断是否为true,如果为false,则往后面一列移动,直到true为止.如果都为false
则回溯到上一级
3.第三行也一样
4.在最后一行找到正确解时,会发生回溯
5.从最后一行回溯到第一行,继续执行1234步骤(这里的回溯相当于返回上一行)

🛹代码实现 

  • 创建一个一维数组并指定其大小
private static final MAX = 8;
private int[]array = new int[MAX];

 为何创建一个一维数组:

  1. 我们可以利用一位数组的下标,作为对应棋盘八行的下标,恰好也只有八个皇后,也能表示各个皇后
  2. 改下标对应的值表示该行的皇后所在的列的下标

图解 

 

 

  •  创建一个输出数组,的方法,以便于我们看到结果
private static void print() {
    for(int i = 0;i < array.length;i++) {
        System.out.print(array[i] + " ");
    }
    System.out.println();
}
  •  创建一个判断的方法
 /**
     *
     * @param n n表示第n+1个皇后和n+1行
     * @return true表示不冲突
     */
    private static boolean judge(int n) {
        for (int i = 0; i < n; i++) {
            if((array[i] == array[n]) || (Math.abs(i - n) == Math.abs(array[i] -array[n]))) {
                return false;
            }
        }
        return true;
    }

代码解析:

  • array[i] == array[n] 比较的是他们是否在同一列
  • (Math.abs(i - n) == Math.abs(array[i] -array[n])比较的是他们是否在同一斜线

说明:若纵坐标之差的绝对值等于横坐标只差的绝对值,则两个坐标在同一斜线上

  • 循环是为了让该皇后与前面的n-1个皇后去比较 

  • 创建一个放置皇后的方法
public static void put(int n) {
        if(n == MAX) {
            print();
            return;
        }
        for (int i = 0; i < MAX; i++) {
            array[n] = i;
            if(judge(n)) {
                put(n + 1);
            }
        }

 代码解析:

  • n==max若成立,则说明n的值为8,从我们创建一维数组的时候就已经得知,第一个皇后应该是0,若这个皇后为8,则说明这个皇后是第9个皇后,根据游戏规则,放满8个即可,说明满足了这个条件就赢了
  • for循环的目的是为了把8列都照顾到,如第一列不行就会跳到第二列,MAX的作用就是限制列
  • 若循环中的条件成立,说明,皇后在此处没有问题,进而放下一个皇后触发递归
  • 若8列都不行则会除法回溯

 图解 

 

  •  完整代码

 

    private static final int MAX = 8;
    private static int[] array = new int[MAX];
    private static int count;
    public static void main(String[] args) {
        put(0);
        System.out.println(count);

    }


    private static void print() {
        count++;
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }

    /**
     *
     * @param n n表示第n+1个皇后和n+1行
     * @return true表示不冲突
     */
    private static boolean judge(int n) {
        for (int i = 0; i < n; i++) {
            if((array[i] == array[n]) || (Math.abs(i - n) == Math.abs(array[i] - array[n]))) {
                return false;
            }
        }
        return true;
    }

    /**
     *
     * @param n 必须为0
     */
    public static void put(int n) {
        if(n == MAX) {
            print();
            return;
        }
        for (int i = 0; i < MAX; i++) {
            array[n] = i;
            if(judge(n)) {
                put(n + 1);
            }
        }
    }

 

结论:

        八皇后问题的代码虽然及其简单,但是理解起来确实是有一定的难度,在小编看来,一维数组的建立是整个算法中的精髓所在,没有这个一维数组的存在后面的代码也不会这么简单,其次,小编有个快速理解八皇后问题的方法:只要符合条件就压栈进入下一行,都不符合就回到上一行,通过这样能完美的将所有的结果输出.

        🚇下一站,排序算法or迷宫

  • 14
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爪哇土著、JOElib

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值