描述
递归(recursion):程序调用自身的编程技巧。
递归满足2个条件:
1)有反复执行的过程(调用自身)
2)有跳出反复执行过程的条件(递归出口)
递归与栈的关系
下面演示的是求n的阶乘
int Factorial(int n){ if (n == 0) return 1; return n * Factorial(n - 1); }
常常听到 “递归的过程就是出入栈的过程”,这句话怎么理解?我们以上述代码为例,取 n=3,则过程如下:
第 1~4 步,都是入栈过程,Factorial(3)调用了Factorial(2),Factorial(2)又接着调用Factorial(1),直到Factorial(0);
第 5 步,因 0 是递归结束条件,故不再入栈,此时栈高度为 4,即为我们平时所说的递归深度;
第 6~9 步,Factorial(0)做完,出栈,而Factorial(0)做完意味着Factorial(1)也做完,同样进行出栈,重复下去,直到所有的都出栈完毕,递归结束。
每一个递归程序都可以把它改写为非递归版本。我们只需利用栈,通过入栈和出栈两个操作就可以模拟递归的过程,二叉树的遍历无疑是这方面的代表。
但是并不是每个递归程序都是那么容易被改写为非递归的。某些递归程序比较复杂,其入栈和出栈非常繁琐,给编码带来了很大难度,而且易读性极差,所以条件允许的情况下,推荐使用递归。
示例题目
1.有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少对?请使用递归和非递归实现。
import java.util.Scanner; public class Main{ /* * 兔子的规律为数列1,1,2,3,5,8,13,21.... 这是一个菲波拉契数列问题 {斐波拉契数列原理:除开前两项 后面每位数等于前两项相加之和} * 1.通过中间值来保存上一月兔子的和 2.在将上一月兔子这一月兔子相加 得到下一月数量和 */ // 非递归 public static void f1(int month) { int rabbit = 1; // 上月兔子的数量和 int newRabbit = 1; // 这一月生成兔子的数量和 int count; // 中间值 用来存数量的 if (month == 1) { System.out.println("第1月兔子 1 对"); } else if (month == 2) { System.out.println("第2月兔子 1 对"); } else { // 从第三月起 for (int i = 3; i <= month; i++) { count = newRabbit; newRabbit = rabbit + newRabbit; rabbit = count; } System.out.println("第" + month + "月兔子 " + newRabbit + " 对"); } } // 递归 public static int f2(int month) { if (month == 1 || month == 2) { return 1; } // 上一个月的兔子数 int rabbit1 = f2(month - 1); // 上一个月的前一个月兔子数 int rabbit2 = f2(month - 2); return rabbit1 + rabbit2; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int month = sc.nextInt(); f1(month); System.out.println("============"); System.out.println("第" + month + "月兔子 " + f2(month) + " 对"); } }
2.十进制转二进制
import java.util.Scanner; /* * 十进制转二进制 */ public class Main { // 非递归 public static void f1(int n) { int t = 0; int bin = 0; int r = 0; while (n != 0) { r = n % 2; n = n / 2; bin += r * Math.pow(10, t); t++; } System.out.println(bin); } // 递归 public static void f2(int n) { if (n / 2 == 0) { System.out.print(n % 2); } else { f2(n / 2); System.out.print(n % 2); } } public static void main(String[] args) { System.out.println("请输入一个非负的十进制整数:"); Scanner sc = new Scanner(System.in); int number = sc.nextInt(); if (number < 0) { System.out.println("不符合要求"); } else { System.out.print("对应的二进制:"); f1(number); System.out.println("================="); System.out.print("对应的二进制:"); f2(number); } } }
原文地址:https://www.cnblogs.com/ericz2j/p/10908794.html
时间: 2024-10-08 19:40:59