目录
递打印&归打印
在前面的文章中讲到,递归有一前提和二要求:一前提是要推导出一个递归公式;二要求是递归应该调用自己本身+有一个趋近于终止的条件。
在此基础上,我们来进一步深入地了解递归,下面通过一个递打印和以一个归打印的例子来讲解:
递打印
public class TestDemo {
public static void reverse(int num){
if(num<=9){
System.out.print(num+" ");
return;
}
System.out.print(num%10+" ");
reverse(num/10);
}
public static void main(String[] args) {
int num=1234;
reverse(num);
}
}
在传递到下一个方法之前就进行打印,也就是在逐渐深入嵌套之前就进行打印称为递打印。
归打印
public class TestDemo {
public static void reverse(int num){
if(num<=9){
System.out.print(num+" ");
return;
}
reverse(num/10);
System.out.print(num%10+" ");
}
public static void main(String[] args) {
int num=1234;
reverse(num);
}
}
在逐渐由深层往浅层(解开递归)的时候进行打印称为归打印。
很显然,如果想要对数字进行逆序打印时,上面的两个方法中只有递打印能够实现,而归打印则会进行顺序打印。因为归打印是会逆过来执行(打印)的,而进行取余操作也是会对数字进行逆序输出,所以结果就是正序的。
其实递打印和归打印可以推广到递执行和归执行的,他们的原理其实时一样的。所以有时候在写递归的代码,一定要想明白自己想要实现的代码中想要执行的部分到底是要在逻辑由浅到深的时候就执行(递执行),还是在逻辑由深到浅之后执行的(归执行),这样才不会照成一些不必要的错误。
当然,也不能总想着这个却忘了之前文章说的思考递归的方法,还是那句话:在思考递归的时候应该横向思考,尽量不要纵向思考递归(容易绕进去)。
汉诺塔
在前面文章中有使用过C语言来实现汉诺塔,详细内容可看这篇文章:
C语言:递归函数实现汉诺塔_蔡欣致的博客-CSDN博客_c语言递归实现汉诺塔C语言:递归函数实现汉诺塔https://blog.csdn.net/Faith_cxz/article/details/122635557?spm=1001.2014.3001.5501接下来是使用Java再来实现一遍汉诺塔,进一步加深对递归的理解。
public class TestDemo {
/**
* 从pos1位置移动到pos2位置
* @param pos1
* @param pos2
*/
public static void move(char pos1,char pos2){
System.out.print(pos1+"->"+pos2+" ");
}
/**
*
* @param n 盘子个数
* @param pos1 起始位置
* @param pos2 中途位置
* @param pos3 目的地位置
*/
public static void hanoi(int n,char pos1,char pos2,char pos3){
if(n==1){
move(pos1,pos3);
return;
}
hanoi(n-1,pos1,pos3,pos2);
move(pos1,pos3);
hanoi(n-1,pos2,pos1,pos3);
}
public static void main(String[] args) {
hanoi(1,'A','B','C');
System.out.println();
hanoi(2,'A','B','C');
System.out.println();
hanoi(3,'A','B','C');
}
}
这整个代码用的就是前面强调的横向思考方式,将大事化小。
青蛙跳台阶
问题:有n个台阶,一只青蛙一次可以跳一个或者两个台阶,试问该青蛙有多少种跳法?
问题拆解:当n==1时,有1种跳法;当n==2时,有2种跳法;当n>2时,即可使用递归来拆分第一次跳一个台阶还是跳两个台阶……如此往复下去,来达到化简问题的效果,具体代码如下:
public class TestDemo {
public static int jumpFloor(int n){
if(n==1){
return 1;
}else if(n==2){
return 2;
}else{
return jumpFloor(n-1)+jumpFloor(n-2);
}
}
public static void main(String[] args) {
System.out.println(jumpFloor(3));
System.out.println(jumpFloor(4));
System.out.println(jumpFloor(5));
}
}
同样还是大事化小的方法。