java中递归的return问题以及八皇后问题的回溯算法分析

递归的return和八皇后问题

一、递归的return问题

1.1递归概念:

方法递归,就是fun(fun(fun(fun()+1)+1)+1)
在方法中调用方法本身,每次的操作步骤相同

1.2问题描述:

在里层return执行完毕之后,会执行外层的return 返回值,导致最后的返回值不对

1.3问题解决:

方法1.外层直接return 方法名(参数); 因为不是return的该层方法的返回值,而是retrun里层方法的返回值,return套return最终它返回值是最里层的
方法2.不要返回值;
方法3.返回值为引用数据类型,因为一直返回的是地址。里面的内容发生改变就是变了。

1.4递归的使用案例:
*数学黑洞6174
//已知:一个任意的四位正整数。将数字重新组合成一个最大的数和最小的数
//相减,重复这个过程,最多七步,必得6174。即:7641-1467=6174。将永远出不
//来。
//求证:所有四位数数字(全相同的除外),均能得到6174。输出掉进黑洞的
//步数。
for (int i = 1000; i <= 9999; i++) {
    System.out.println("=========================");
    System.out.println(i);
    System.out.println(mathBH(i));

    System.out.println("=========================");

}
--------------------------------------------------------------------
static int count=0;
private static int mathBH(int i) {
    int ge=i%10;
    int shi=i/10%10;
    int bai=i/100%10;
    int qian=i/1000;
    if(ge==shi&&ge==bai&&ge==qian){
        return -1;
    }else {
        int[] num13={ge,shi,bai,qian};
        Arrays.sort(num13);
        int max1=num13[3]*1000+num13[2]*100+num13[1]*10+num13[0];
        int min1=num13[0]*1000+num13[1]*100+num13[2]*10+num13[3];
        int num=max1-min1;
        count++;
        if(num==6174){
            System.out.println(count);
            int countLast=count;
            count=0;
            return countLast;
        }else {
            return mathBH(num);  //注意这里的技巧,直接return方法本身的返回值,那么后面就不存在,多余的return问题了。

        }
    }

}
1.5递归的使用--------回溯算法:

原理:调用自身方法,有返回值,且返回值中不含有return;
真正产生回溯现象的原因是:参数的作用域问题,里层方法的参数n作用域只在里层,当里层的方法执行完成的时候,继续执行外层的方法,外层的方法的参数还是外层传入的n,内外层的n只是在表现形式上都叫n,其实本质上对JVM来说里外层的n本质是不一样的。
联想内存图,每调用一个方法就会有一个方法进栈,在最上面的方法(n=8)执行完成后,就会弹栈,然后执行现在最高层的代码,而这个代码里面的n是7*

二、八皇后问题

2.1八个皇后问题案例(问题分析中注意算法和内存图的结合):
八皇后问题
//在8×8 的国际象棋盘上,放置八个皇后,使任何一个皇后都不能吃掉另一
//个。国际象棋规则中,皇后可以吃到任何一个与他在同一行、同一列或者同一斜
//线上的敌方棋子,所以八皇后问题的所有解满足:8 个皇后都不在同一行、同一
//列,或者同一斜线上。
//输出所有的解。
//提示:使用递归。
public class Test {
    static int[] queens = new int[8]; //表示每一行皇后的纵坐标
    static int solveNum = 1; //统计解的数量
    public static void main(String[] args) {
        put(0);

    }
    //判断在之前的基础上在第n行放第m列是否可行
    public static boolean canPut(int n, int m){
        //判断是否有在同一列的
        for(int i = 0; i<n; i++){
            if (queens[i] == m) return false;
        }
        //判断是否有在左上-->右下对角线
        for(int i = 0; i<n; i++){
            if (queens[i] - i == m - n) return false;
        }

        //判断是否有在右上-->左下对角线
        for(int i = 0; i<n; i++){
            if (queens[i] + i == m + n) return false;
        }
        return true;
    }

    //表示尝试放置第n行的皇后
    public static void put(int n){
        if (n == 8){
            System.out.println("=============================");
            System.out.println(solveNum++);
            printQueen();
            return;
        }
        for(int i = 0; i<queens.length; i++){
            if (canPut(n, i)){
                queens[n] = i;
                put(n+1);
                queens[n] = 0;   //注意这里的n是外层的n,正因为外层方法的n
                				//是外层的n,所以产生了回溯现象
            }
        }

    }
    public static void printQueen(){
        for(int i = 0; i<queens.length; i++){
            for(int j = 0; j<queens.length; j++){
                if (queens[i] == j){
                    System.out.print("*  ");
                }else{
                    System.out.print("0  ");
                }
            }
            System.out.println();
        }
    }
}
2.2八皇后问题中回溯算法实现分析:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值