什么是递归
遇到的问题直接并不好解决,但是发现将原问题拆分成其子问题之后,子问题与原问题有相同的解法,等子问题解决之后,原问题就迎刃而解了。
递归的概念
一个方法在执行过程中调用自身, 就称为 “递归”.
递归相当于数学上的 “数学归纳法”, 有一个起始条件, 然后有一个递推公式.
例如, 我们求 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');
}
输出结果:
以上内容如果对诸位有帮助的话可以留下你们的赞赞,如果我书写的有问题,请在评论区指出,我会及时修改的。