🚗前言:
八皇后问题是经典的算法问题,其独特的游戏玩法总是令人绞尽脑汁的同时又津津乐道,但是在我们写代码的时候又觉得,八皇后问题无从下手,对此可爱的博主根据自己学到的知识写了这篇博客,让大家跟随着作者的脚步,一同学会八皇后问题的真确解
咱们从一下的方面展开阐述:
八皇后问题的定义 ➡️ 八皇后问题的思路 ➡️ 八皇后问题的代码实现与代码分析 ➡️ 结论
如果喜欢本博客戳这关注作者😘吧!
↘️往期精彩:
🚓八皇后问题概述:
在一个8*8的棋盘中(有点类似于国际象棋那种黑白棋盘),放置皇后,放置皇后的时候必须遵守以下规则
- 放置的皇后不能在同一行,同一列,同一斜线
- 皇后必须从第一行开始放起
- 如皇后能放到最后一行则表示游戏成功
看到这,相信小伙伴都觉得 ,且继续往下看
🦽八皇后问题的思路:
传统思路:
- 创建一个二维数组
- 一个一个去放,并判断是否在同一直线,同一列,同一斜线,如果是就放,不是就改
- 循环到最后得出结果
回溯思路:
- 创建一个一维数组并指定其容量(一维数组应该是个静态引用)
- 创建一个判断方法
- 利用递归迭代完成代码
1.在第一行第一列放一个皇后 2.在第二行第一列放一个皇后,判断是否为true,如果为false,则往后面一列移动,直到true为止.如果都为false 则回溯到上一级 3.第三行也一样 4.在最后一行找到正确解时,会发生回溯 5.从最后一行回溯到第一行,继续执行1234步骤(这里的回溯相当于返回上一行)
🛹代码实现
- 创建一个一维数组并指定其大小
private static final MAX = 8;
private int[]array = new int[MAX];
为何创建一个一维数组:
- 我们可以利用一位数组的下标,作为对应棋盘八行的下标,恰好也只有八个皇后,也能表示各个皇后
- 改下标对应的值表示该行的皇后所在的列的下标
图解
- 创建一个输出数组,的方法,以便于我们看到结果
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迷宫