两种类型

  • 尾递归:直接转就行

AcWing 717. 简单斐波那契
二叉树的前序遍历

  1. // 例子:斐波那契数列
  2. // 尾递归形式
  3. import java.util.*;
  4. public class Main {
  5. public static void main(String[] args) {
  6. Scanner sc = new Scanner(System.in);
  7. int n = sc.nextInt();
  8. dfs(0, 1, 1, n);
  9. }
  10. static void dfs(int a, int b, int u, int n) {
  11. if (u > n) return;
  12. if (u == 1) {
  13. System.out.print(a + " ");
  14. dfs(a, b, u + 1, n);
  15. } else if (u == 2) {
  16. System.out.print(b + " ");
  17. dfs(a, b, u + 1, n);
  18. } else {
  19. System.out.print(a + b + " ");
  20. int t = a + b;
  21. a = b;
  22. b = t;
  23. dfs(a, b, u + 1, n);
  24. }
  25. }
  26. }
  1. // 迭代写法
  2. import java.util.*;
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. int n = sc.nextInt();
  7. int a = 0, b = 1;
  8. for (int i = 1; i <= n; i++) {
  9. if (i == 1) {
  10. System.out.print(a + " ");
  11. } else if (i == 2) {
  12. System.out.print(b + " ");
  13. } else {
  14. int t = a + b;
  15. System.out.print(t + " ");
  16. a = b;
  17. b = t;
  18. }
  19. }
  20. }
  21. }
  • 普通递归

使用栈维护

  1. 参数
  2. 局部变量
  3. 返回位置

Acwing 93. 递归实现组合型枚举

  1. // 递归写法
  2. import java.util.*;
  3. public class Main {
  4. static int n, m;
  5. static int[] res = new int[30];
  6. public static void main(String[] args) {
  7. Scanner sc = new Scanner(System.in);
  8. n = sc.nextInt();
  9. m = sc.nextInt();
  10. dfs(1, 1);
  11. }
  12. static void dfs(int u, int start) {
  13. if (u == m + 1) {
  14. for (int i = 1; i <= m; i++)
  15. System.out.print(res[i] + " ");
  16. System.out.println();
  17. return;
  18. }
  19. for(int i = start; i + m - u <= n; i++) {
  20. res[u] = i;
  21. dfs(u + 1, i + 1);
  22. }
  23. }
  24. }
  1. // 迭代写法
  2. import java.util.*;
  3. public class Main {
  4. static int n, m;
  5. static int[] res = new int[30];
  6. public static void main(String[] args) {
  7. Scanner sc = new Scanner(System.in);
  8. n = sc.nextInt();
  9. m = sc.nextInt();
  10. Deque<State> stk = new LinkedList<>();
  11. stk.offer(new State(0, 1, 1));
  12. while (!stk.isEmpty()) {
  13. State t = stk.pop();
  14. if (t.pos == 0) {
  15. if (t.u == m + 1) {
  16. for (int i = 1; i <= m; i++)
  17. System.out.print(res[i] + " ");
  18. System.out.println();
  19. continue;
  20. }
  21. if (t.start + m - t.u <= n) {
  22. res[t.u] = t.start;
  23. t.pos++; t.start++;
  24. stk.push(t);
  25. stk.push(new State(0, t.u + 1, t.start));
  26. }
  27. } else if (t.pos == 1) {
  28. if (t.start + m - t.u <= n) {
  29. res[t.u] = t.start;
  30. t.start++;
  31. stk.push(t);
  32. stk.push(new State(0, t.u + 1, t.start));
  33. }
  34. }
  35. }
  36. }
  37. }
  38. class State {
  39. int pos, u, start;
  40. State(int pos, int u, int start) {
  41. this.pos = pos;
  42. this.u = u;
  43. this.start = start;
  44. }
  45. }

其它:

  • 二叉树的中序/后序遍历
递归 栈模拟
优点 编码容易、可读性强、易于维护。 执行效率较高。
缺点 递归方法逐层调用函数会产生一定性能消耗,如果递归深度较深,可能会抛出 StackOverflow 异常。 不是所有的递归都可以很容易地通过模拟栈来实现。显式编写栈的代码较难理解,不易于维护。