初始Java~递归~汉诺塔

什么是递归

在这里插入图片描述

遇到的问题直接并不好解决,但是发现将原问题拆分成其子问题之后,子问题与原问题有相同的解法,等子问题解决之后,原问题就迎刃而解了。

递归的概念

一个方法在执行过程中调用自身, 就称为 “递归”.
递归相当于数学上的 “数学归纳法”, 有一个起始条件, 然后有一个递推公式.

例如, 我们求 N!
起始条件: N = 1 的时候, N! 为 1. 这个起始条件相当于递归的结束条件.
递归公式: 求 N! , 直接不好求, 可以把问题转换成 N! => N * (N-1)!
递归
5的阶乘 :
在这里插入图片描述

递归执行过程分析

递归的程序的执行过程不太容易理解, 要想理解清楚递归, 必须先理解清楚 “方法的执行过程”, 尤其是 “方法执行结束之后, 回到调用位置继续往下执行”.

举例:通过递归写出n的阶乘

public static int fac(int n) {
        if(n == 1) {
            return 1;
        }
        int tmp = fac(n-1)*n;
        return tmp;
    }

过程分析
在这里插入图片描述

关于 “调用栈”
方法调用的时候, 会有一个 “栈” 这样的内存空间描述当前的调用关系. 称为调用栈.
每一次的方法调用就称为一个 “栈帧”, 每个栈帧中包含了这次调用的参数是哪些, 返回到哪里继续执行等信息.

递归练习

代码示例1 按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)

public static void print(int n) {
//        if(n>9) {
//            print(n/10);
//        }
//        System.out.print(n%10+" ");
        if(n<=9) {
            System.out.print(n+" ");
            return;
        }
        print(n/10);
        System.out.print(n%10+" ");

    }

代码示例2 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19

public static int func(int n) {
        if(n<=9) {
            return n;
        }
        return n%10 + func(n/10);
    }

代码示例3 求斐波那契数列的第 N 项(最好使用循环来实现递归的话有太多的重复计算。)

 public static int fibnacio(int n) {
        if(n == 1||n == 2) {
            return 1;
        }
        return fibnacio(n-1)+fibnacio(n-2);
    }

汉诺塔

在这里插入图片描述
当A上有一个盘子 :A - >C
当A上有两个盘子 :A - >B A - >C B - >C
当A上有三个盘子 :A - >C A - >B C - >B A - >C B - >A B - >C A - >C
找规律
分别是一到三个盘子时的转换次数是 1 3 7 由此可找到规律 在第n个盘子的转换次数是
2^n-1
在这里插入图片描述
思维方式

当A上面有n个盘子要将其都放在C中 可以把n上面的n-1个盘子看作一个整体这样就假设A中有两个盘子先将n-1的盘子通过C全部转换到B中 将a的第n个盘子放到C中最后在将n-1个盘子通过A全部转到C中。依次类推这时候n-1个盘子在B上要转换到C上,实现将n-2看作一个整体通过C将n-2转换到A上面最后将第n-1位置的盘子放到C中,此时n-2个盘子又回到A中在通过n个盘子相同的路径转像C,n-3个盘子到达了B上此时可以通过n-1个盘子时的路径转换了。

代码方式

 public static void hanota(int n,char pos1,char pos2,char pos3) {
        if(n == 1) {
            move(pos1,pos3);
            return;
        }
        hanota(n-1,pos1,pos3,pos2);//将A上面的n-1个盘子通过C转换到B盘子上
        move(pos1,pos3);//当完成了上一项此时A上面值剩下了一个盘中 这时候将A上面的盘子移动到C上
        hanota(n-1,pos2,pos1,pos3);//经过上面的移动此时n-1个盘子在B上此时B借助A移动到C中。
    }
    public static void move(char pos1,char pos2) {
        
        System.out.print(pos1+"->"+pos2+" ");
    }

    public static void main2(String[] args) {
        hanota(1,'A','B','C');
        System.out.println();
        hanota(2, 'A', 'B', 'C');
        System.out.println();
        hanota(3,'A','B','C');
    }

输出结果:

在这里插入图片描述

以上内容如果对诸位有帮助的话可以留下你们的赞赞,如果我书写的有问题,请在评论区指出,我会及时修改的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值