本文目录导读:

我来为你介绍Java递归方法的编写案例,从基础到进阶,包含详细解释。
基础递归示例:阶乘计算
public class FactorialExample {
// 计算n的阶乘
public static int factorial(int n) {
// 基准情况:0! = 1
if (n == 0 || n == 1) {
return 1;
}
// 递归情况:n! = n * (n-1)!
return n * factorial(n - 1);
}
// 带详细打印的版本,帮助理解递归过程
public static int factorialWithTrace(int n, int depth) {
// 打印递归深度
String indent = " ".repeat(depth);
System.out.println(indent + "factorial(" + n + ") 调用");
if (n == 0 || n == 1) {
System.out.println(indent + "返回 1");
return 1;
}
int result = n * factorialWithTrace(n - 1, depth + 1);
System.out.println(indent + factorial(n - 1) + " * " + n + " = " + result);
return result;
}
public static void main(String[] args) {
System.out.println("5! = " + factorial(5));
System.out.println("\n递归过程追踪:");
factorialWithTrace(5, 0);
}
}
斐波那契数列
public class FibonacciExample {
// 基础递归版本(效率较低)
public static int fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
// 优化版本:使用记忆化递归(动态规划)
private static int[] memo;
public static int fibonacciOptimized(int n) {
memo = new int[n + 1];
return fibHelper(n);
}
private static int fibHelper(int n) {
if (n <= 1) {
return n;
}
// 如果已经计算过,直接返回
if (memo[n] != 0) {
return memo[n];
}
// 计算并存储结果
memo[n] = fibHelper(n - 1) + fibHelper(n - 2);
return memo[n];
}
public static void main(String[] args) {
int n = 10;
System.out.println("斐波那契数列第" + n + "项:");
System.out.println("基础版本: " + fibonacci(n));
System.out.println("优化版本: " + fibonacciOptimized(n));
}
}
二叉树遍历
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
public class BinaryTreeTraversal {
// 前序遍历:根 -> 左 -> 右
public static void preorder(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.val + " ");
preorder(root.left);
preorder(root.right);
}
// 中序遍历:左 -> 根 -> 右
public static void inorder(TreeNode root) {
if (root == null) {
return;
}
inorder(root.left);
System.out.print(root.val + " ");
inorder(root.right);
}
// 后序遍历:左 -> 右 -> 根
public static void postorder(TreeNode root) {
if (root == null) {
return;
}
postorder(root.left);
postorder(root.right);
System.out.print(root.val + " ");
}
// 计算树的高度
public static int height(TreeNode root) {
if (root == null) {
return 0;
}
return 1 + Math.max(height(root.left), height(root.right));
}
public static void main(String[] args) {
// 创建一棵二叉树
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
System.out.println("前序遍历:");
preorder(root);
System.out.println("\n中序遍历:");
inorder(root);
System.out.println("\n后序遍历:");
postorder(root);
System.out.println("\n树的高度:" + height(root));
}
}
汉诺塔问题
public class HanoiTower {
// 移动步骤计数
private static int stepCount = 0;
public static void hanoi(int n, char from, char to, char aux) {
// 基准情况:只有一个盘子
if (n == 1) {
stepCount++;
System.out.println("步骤" + stepCount + ": 移动盘子1从" + from + "到" + to);
return;
}
// 将n-1个盘子从from移动到aux
hanoi(n - 1, from, aux, to);
// 移动最大的盘子
stepCount++;
System.out.println("步骤" + stepCount + ": 移动盘子" + n + "从" + from + "到" + to);
// 将n-1个盘子从aux移动到to
hanoi(n - 1, aux, to, from);
}
// 只计算最少步数
public static int calculateMinSteps(int n) {
return (int) Math.pow(2, n) - 1;
}
public static void main(String[] args) {
int n = 3;
System.out.println("汉诺塔问题(" + n + "个盘子):");
hanoi(n, 'A', 'C', 'B');
System.out.println("\n总步数:" + stepCount);
System.out.println("理论最少步数:" + calculateMinSteps(n));
}
}
数组查找和排序
public class RecursiveSearchSort {
// 二分查找(递归版本)
public static int binarySearch(int[] arr, int left, int right, int target) {
if (left > right) {
return -1; // 未找到
}
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
return binarySearch(arr, left, mid - 1, target);
} else {
return binarySearch(arr, mid + 1, right, target);
}
}
// 归并排序(递归版本)
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
// 递归排序左右两半
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// 合并已排序的两半
merge(arr, left, mid, right);
}
}
private static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
// 复制数据到临时数组
for (int i = 0; i < n1; i++) {
leftArr[i] = arr[left + i];
}
for (int j = 0; j < n2; j++) {
rightArr[j] = arr[mid + 1 + j];
}
// 合并临时数组
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j]) {
arr[k] = leftArr[i];
i++;
} else {
arr[k] = rightArr[j];
j++;
}
k++;
}
// 复制剩余元素
while (i < n1) {
arr[k] = leftArr[i];
i++;
k++;
}
while (j < n2) {
arr[k] = rightArr[j];
j++;
k++;
}
}
public static void main(String[] args) {
// 二分查找测试
int[] sortedArr = {1, 3, 5, 7, 9, 11, 13};
int target = 7;
int index = binarySearch(sortedArr, 0, sortedArr.length - 1, target);
System.out.println("查找" + target + "的位置:" + (index != -1 ? index : "未找到"));
// 归并排序测试
int[] unsortedArr = {38, 27, 43, 3, 9, 82, 10};
System.out.println("\n排序前:");
for (int num : unsortedArr) {
System.out.print(num + " ");
}
mergeSort(unsortedArr, 0, unsortedArr.length - 1);
System.out.println("\n排序后:");
for (int num : unsortedArr) {
System.out.print(num + " ");
}
}
}
编写递归的关键要点
public class RecursionGuidelines {
/**
* 编写递归方法的核心原则:
*
* 1. 基准情况(Base Case):必须有终止条件
* 2. 递归情况(Recursive Case):必须向基准情况靠近
* 3. 问题分解:将大问题分解为相似的小问题
* 4. 子问题独立:各子问题之间不应该相互依赖
*/
// 示例:计算数组元素之和
public static int sumArray(int[] arr, int index) {
// 基准情况
if (index >= arr.length) {
return 0;
}
// 递归情况
return arr[index] + sumArray(arr, index + 1);
}
// 尾递归优化的例子
public static int sumArrayTail(int[] arr, int index, int accumulator) {
if (index >= arr.length) {
return accumulator;
}
return sumArrayTail(arr, index + 1, accumulator + arr[index]);
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
System.out.println("数组求和:" + sumArray(numbers, 0));
System.out.println("尾递归求和:" + sumArrayTail(numbers, 0, 0));
}
}
递归的优缺点
优点:
- 代码简洁、逻辑清晰
- 某些问题(如树、图的遍历)天然适合递归
- 解决问题的思路符合直觉
缺点:
- 可能造成栈溢出(StackOverflowError)
- 效率可能比迭代低(函数调用开销)
- 难以调试和优化
适用场景:
- 树、图的数据结构操作
- 分治算法(快速排序、归并排序)
- 回溯算法
- 数学计算(阶乘、斐波那契)
通过以上案例,你可以看到递归方法在不同的场景下的应用,建议先从简单的例子开始实践,慢慢掌握递归的思想。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播