递归用法八皇后问题java实现

八皇后问题

八皇后问题是指任何两个皇后不能处在同一行、同一列、同一斜线上,问有多少种摆法。
思路分析:
在这里插入图片描述
当取得一个正确解的时候,他会把第一个皇后所在位置的所有解先求出来。比如说:他会把(1,1)这个位置中皇后所有的解求出来。

编程分析

正常编程是需要用二维数组来代表棋盘,但是也可以使用一维数据进行编程。比如ints[0] = 0就可以代表第一行第一列,ints[a][b]代表的第a+1行,b+1列。

/**
 * FileName: Queue8
 *
 * @Author:luguobao Date: 2020/4/2010:22
 * Description:
 * History:
 * <author>   <time>   <version>   <desc>
 * 作者姓名    修改时间    版本号       描述
 */
public class Queue8 {
    static int max = 8;
    static int[] ints = new int[max];
    static int count = 0;
    public static void main(String[] args) {
        put(0);
        System.out.println("解决方式有" + count);
    }
    /**
     * 对棋盘中元素进行输出
     */
    public static void out(){
        count++;
        for (int i = 0; i < max; i++) {
            System.out.print(ints[i]);
        }
        System.out.println();
    }

    /**
     *
     * @param n 第n个皇后是不是和之前的皇后有冲突。
     *          第n个皇后肯定是在第n行的。
     * @return
     */
    public static boolean judge(int n){
        for (int i = 0; i < n; i++) {
            //判断列是否相等,或者是否在斜线上
            if(ints[i] == ints[n] || n-i  == Math.abs(ints[n] - ints[i])){
                return false;
            }
        }//当第n个皇后与之前皇后都不冲突的时候,才返回true。
            return true;

    }

    /**
     *
     * @param n 对第n个皇后进行放置,注意因为ints[n],n是从0开始的。
     *          在调用这个方法的时候,需要把他从0开始调用。
     * @return
     */
    public static void put(int n){
        if(n == max){
            //如果n=8,代表,数组中已经有8个数了,则将其结果进行输出。
            out();
            return;
        }
        for (int i = 0; i < max; i++) {
            //从第一列开始放置
            ints[n] = i;
            //如果放在i列不冲突的话,再放置第二个
            if(judge(n)){
                put(n+1);
            }
            //如果冲突的话,再换一列再试。
        }
    }
}

结果输出为:
在这里插入图片描述
对put()方法进行分析:

/**
     *
     * @param n 对第n个皇后进行放置,注意因为ints[n],n是从0开始的。
     *          在调用这个方法的时候,需要把他从0开始调用。
     * @return
     */
    public static void put(int n){
        if(n == max){
            //如果n=8,代表,数组中已经有8个数了,则将其结果进行输出。
            out();
            return;
        }
        for (int i = 0; i < max; i++) {
            //从第一列开始放置
            ints[n] = i;
            //如果放在i列不冲突的话,再放置第二个
            if(judge(n)){
                put(n+1);
            }
            //如果冲突的话,再换一列再试。
        }
    }

由于有for循环,故就算它找到了一种方法,比如最后一种73025164 它还是会往后面判断730251645。故其实他的判断次数有15000多次。但是,如果,第一次放7位置,第二次放的也是7位置就不会向后面判断了因为本身judge就返回false,故不会执行put(3)了,这就是为什么判断不是8的8次方的原因。但是,如果第一次放0位置,第二次放2、3、4、5、6、7都是可以判断成功的,则她们都会相应的进行执行,不会拉下。直到输出,或者执行不了。这就是递归的回溯用法。

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值