数据结构与算法----递归

递归

简单介绍

最直接的就是:递归在一直反复调用自身函数进行解决问题

递归有两个重要概念:

  • 递归边界(终止条件):定义递归何时停止,避免无限调用。

  • 递归式(递归调用):描述如何将问题分解为更小的子问题,并通过调用自身得到结果。

分治思想

分治法是一种重要的算法思想,它将原问题划分为若干个规模较小但结构与原问题相似的子问题,分别解决这些子问题,最后将子问题的解合并为原问题的解。

递归是实现分治思想的一种常见方式,但分治也可以通过迭代等其他方法实现。

大致步骤:

  1. 分解:将原问题划分为若干个规模较小、结构相似的子问题。

  2. 解决:递归地求解子问题;当子问题规模足够小(通常达到递归边界)时,直接求解。

  3. 合并:将所有子问题的解合并,得到原问题的最终解。

注意事项:

  • 子问题之间应相互独立、无交叉,否则可能导致重复计算或逻辑错误。

  • 分治法适用于问题具有“可分解性”和“子问题可合并性”的场景。

示例

一、求解:n!(n的阶乘)

问题描述

计算一个非负整数 n 的阶乘,即

例如,

递归思路
  • 递归边界:n=0 或 n=1时,n!=1(注意:数学上 0!=1)。

  • 递归式:

代码实现
 #include
 using namespace std;
 ​
 int F(int n) {
     if (n == 0 || n == 1) return 1; // 递归边界
     return F(n - 1) * n;           // 递归式
 }
 ​
 int main() {
     int n;
     cin >> n;                      // 输入非负整数 n
     cout << F(n) << endl;          // 输出 n!
     return 0;
 }
运行示例
  • 输入:5

  • 输出:120

注意
  • 输入 nnn 应为非负整数,否则需添加输入校验。

  • 递归深度过大(如 nnn 太大)可能导致栈溢出。

二、斐波那契数列

问题描述

斐波那契数列是一个数列,其中每个数是前两个数的和。通常定义为:

  • F(0)=0

  • F(1)=1

  • F(n)=F(n−1)+F(n−2)

例如:0, 1, 1, 2, 3, 5, 8, 13, 21, ...

递归思路
  • 递归边界:n=0时返回 0,n=1时返回 1。

  • 递归式:F(n)=F(n−1)+F(n−2)

 #include
 using namespace std;
 ​
 int F(int n) {
     if (n == 0) return 0;          // 递归边界
     if (n == 1) return 1;          // 递归边界
     return F(n - 1) + F(n - 2);    // 递归式
 }
 ​
 int main() {
     int n;
     cin >> n;                      // 输入非负整数 n
     cout << F(n) << endl;          // 输出第 n 个斐波那契数
     return 0;
 }
运行示例
  • 输入:6

  • 输出:8

注意
  • 该实现的时间复杂度为 O(2n),效率较低,因为存在大量重复计算(如 F(n−1))和 F(n−2)会重复计算子问题)。

  • 优化方法:可以使用动态规划或记忆化递归,将时间复杂度降至 O(n)。

递归的优缺点

优点

  • 代码简洁,逻辑清晰(如树遍历)。

  • 天然适合分治类问题。

缺点

  • 栈溢出:递归深度过大会导致栈溢出。

  • 重复计算:如斐波那契递归存在大量重复计算(可通过记忆化优化)。

  • 效率低:函数调用开销较大。

常见错误及避免

  1. 缺失递归边界:导致无限递归,务必优先定义边界条件。

  2. 错误合并结果:分治问题需确保合并逻辑正确。

  3. 忽略重复计算:对重叠子问题使用记忆化优化。

递归优化技巧

  1. 尾递归:递归调用放在函数末尾,避免栈帧累积(部分语言支持尾递归优化)。

  2. 记忆化:记录已计算的子问题结果,避免重复计算。

  3. 迭代替代:对于简单递归问题,可用循环实现以节省空间。

其他经典示例

  1. 汉诺塔问题:通过递归将大问题分解为移动单个盘子和递归移动子塔。

  2. 二叉树遍历:前序、中序、后序遍历都可用递归实现。

  3. 快速排序:通过递归划分数组实现排序。

  4. 回溯算法:如八皇后问题,递归尝试所有可能路径。

你可能感兴趣的:(算法,算法,C++,数据结构)