
🔥个人主页:@草莓熊Lotso 🎬作者简介:C++研发方向学习者 📖个人专栏: 《C语言》 《数据结构与算法》《C++知识分享》《编程工具入门指南》 ⭐️人生格言:生活是默默的坚持,毅力是永久的享受。
前言:在 C++ 编程中,递归和迭代是解决重复计算问题的两种基本方法。它们各有优缺点,适用于不同的场景。本篇博客将深入探讨这两种编程范式,分析它们的工作原理、适用场景以及在实际开发中的应用。
递归 (Recursion) 是指函数通过调用自身来解决问题的一种方法。递归函数通常包含两个部分:
阶乘是递归的经典案例,n 的阶乘定义为 n! = n × (n-1) × ... × 1,且 0! = 1。
#include <iostream>
using namespace std;
// 递归计算阶乘
unsigned long long factorialRecursive(int n) {
    // 基本情况
    if (n == 0) {
        return 1;
    }
    // 递归步骤
    return n * factorialRecursive(n - 1);
}
int main() {
    int num = 10;
    cout << num << "! = " << factorialRecursive(num) << endl;
    return 0;
}迭代 (Iteration) 是通过循环结构(如 for、while)重复执行一段代码来解决问题的方法。迭代通常使用循环变量控制循环的开始和结束。
同样是阶乘计算,我们可以用迭代方式实现:
#include <iostream>
using namespace std;
// 迭代计算阶乘
unsigned long long factorialIterative(int n) {
    unsigned long long result = 1;
    // 使用for循环进行迭代
    for (int i = 1; i <= n; ++i) {
        result *= i;
    }
    return result;
}
int main() {
    int num = 10;
    cout << num << "! = " << factorialIterative(num) << endl;
    return 0;
}有些问题既可以用递归实现,也可以用迭代实现。下面以斐波那契数列为例展示如何将递归转换为迭代。
斐波那契数列定义:F (0) = 0, F (1) = 1, F (n) = F (n-1) + F (n-2)
// 递归实现斐波那契数列
int fibonacciRecursive(int n) {
    if (n <= 1) {
        return n;
    }
    return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);
}// 迭代实现斐波那契数列
int fibonacciIterative(int n) {
    if (n <= 1) {
        return n;
    }
    
    int prev_prev = 0; // F(n-2)
    int prev = 1;      // F(n-1)
    int current;       // F(n)
    
    for (int i = 2; i <= n; ++i) {
        current = prev + prev_prev;
        prev_prev = prev;
        prev = current;
    }
    
    return current;
}有些递归可以改写为尾递归形式,即递归调用是函数的最后一个操作。某些编译器(如 GCC)会对尾递归进行优化,将其转换为类似迭代的形式,避免栈溢出。
以阶乘计算为例,尾递归版本如下:
// 尾递归计算阶乘
unsigned long long factorialTailRecursive(int n, unsigned long long accumulator = 1) {
    if (n == 0) {
        return accumulator;
    }
    // 递归调用是函数的最后一个操作
    return factorialTailRecursive(n - 1, n * accumulator);
}二叉树遍历是递归的典型应用场景,代码简洁直观:
#include <iostream>
#include <stack>
using namespace std;
// 二叉树节点结构
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
// 递归先序遍历
void preorderRecursive(TreeNode* root) {
    if (root == nullptr) return;
    cout << root->val << " ";       // 访问根节点
    preorderRecursive(root->left);  // 遍历左子树
    preorderRecursive(root->right); // 遍历右子树
}
// 迭代先序遍历
void preorderIterative(TreeNode* root) {
    if (root == nullptr) return;
    
    stack<TreeNode*> s;
    s.push(root);
    
    while (!s.empty()) {
        TreeNode* node = s.top();
        s.pop();
        
        cout << node->val << " ";   // 访问根节点
        
        // 右子树先入栈,左子树后入栈,保证左子树先访问
        if (node->right != nullptr) {
            s.push(node->right);
        }
        if (node->left != nullptr) {
            s.push(node->left);
        }
    }
}
int main() {
    // 构建一个简单的二叉树
    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);
    
    cout << "递归先序遍历: ";
    preorderRecursive(root);
    cout << endl;
    
    cout << "迭代先序遍历: ";
    preorderIterative(root);
    cout << endl;
    
    // 释放内存(实际应用中应编写完整的销毁函数)
    delete root->left->left;
    delete root->left->right;
    delete root->left;
    delete root->right;
    delete root;
    
    return 0;
}总结:
递归和迭代是 C++ 中两种重要的编程范式,各有其适用场景:
往期回顾:
结语:我们应该根据具体问题的性质、规模和性能要求,选择最合适的方法。在实际开发中,有时也可以结合两种方法的优势,例如使用递归设计算法,再转换为迭代实现以提高性能。掌握递归与迭代的转换技巧,能够帮助我们更好地理解算法本质,并在实际编程中灵活应用。如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。