C++中使用递归函数

C++中使用递归函数

在有些情况下,可让函数调用它自己,这样的函数称为递归函数。递归函数必须有明确的退出条件,满足这种条件后,函数将返回,而不再调用自己。

如果一个函数在其定义中又调用自身,则称为递归函数,调用自身的过程叫做递归。

递归分为直接递归和间接递归。直接递归是指函数直接调用自身,间接递归则指 A 函数调用了其它函数,而其它的函数中又调用了 A 函数。

递归函数通常由以下两个部分组成:

  • 基本情况(Base Case):这是递归的终止条件。没有基本情况,递归函数将无限地调用自己,导致栈溢出。
  • 递归情况(Recursive Case):在这里,函数将问题分解成更小的子问题,并自我调用来解决这些子问题。

实际场景中,很多问题适合用递归函数来解决。

计算一个阶乘(n!)是递归的经典应用之一,求 n! 的递归函数如下:

cpp 复制代码
#include <iostream>

int fibonacci(int n) {
    // 基本情况
    if (n == 0) return 0;
    if (n == 1) return 1;
    // 递归情况
    return fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
    int result = fibonacci(5);  // 第5个Fibonacci数是5
    std::cout << "The 5th Fibonacci number is: " << result << std::endl;
    return 0;
}

程序运行后,factorial(5) 函数会被调用,这是一个递归函数,它的执行过程如下:

  • factorial(5) 被调用,基本情况 n==0 不成立,所以进入递归情况,计算 5*factorial(4);
  • factorial(4) 被调用,基本情况 n==0 不成立,所以进入递归情况,计算 4*factorial(3);
  • factorial(3) 被调用,基本情况 n==0 不成立,所以进入递归情况,计算 3*factorial(2);
  • factorial(2) 被调用,基本情况 n==0 不成立,所以进入递归情况,计算 2*factorial(1);
  • factorial(1) 被调用,基本情况 n==0 不成立,所以进入递归情况,计算 1*factorial(0);
  • factorial(0) 被调用,基本情况 n==0 成立,返回 1。

此时递归开始"展开",并且每一层递归都会返回其结果:

  • factorial(1) 计算 1*1=1,所以返回 1;
  • factorial(2) 计算 2*1=2,所以返回 2;
  • factorial(3) 计算 3*2=6,所以返回 6;
  • factorial(4) 计算 4*6=24,所以返回 24;
  • factorial(5) 计算 5*24=120,所以返回 120。

最后在 main() 函数中,factorial(5) 的结果 120 被赋值给变量 result,然后输出到控制台。

因此,这个递归函数的执行过程首先是"深入"(从 factorial(5) 到 factorial(0)),然后是"展开"(从 factorial(0) 返回到 factorial(5)),在这个过程中逐步完成阶乘的计算。每一层递归都依赖于其下一层的结果,直到达到基本情况,然后逐层返回计算结果。

警告:

如果没有退出条件或存在 bug,递归函数可能不断调用自己,直到栈溢出后才停止,导致应用程序崩溃。

计算斐波纳契数列时,递归函数很有用,如程序清单 7.5 所示。该数列的开头两个数为 0 和 1:

F(0) = 0
F(1) = 1

随后的每个数都是前两个数之和。计算第 n 个数( n>1)的公式如下:

Fibonacci(n) = Fibonacci(n - 1) + Fibonacci(n - 2)

因此斐波纳契数列如下:

F(2) = 1
F(3) = 2
F(4) = 3
F(5) = 5
F(6) = 8, and so on.

使用递归函数计算斐波纳契数列中的数字:

cpp 复制代码
#include <iostream>
using namespace std;

int GetFibNumber(int fibIndex)
{
    if (fibIndex < 2)
        return fibIndex;
    else // recursion if fibIndex >= 2
        return GetFibNumber(fibIndex - 1) + GetFibNumber(fibIndex - 2);
}

int main()
{
    cout << "Enter 0-based index of desired Fibonacci Number: ";
    int index = 0;
    cin >> index;

    cout << "Fibonacci number is: " << GetFibNumber(index) << endl;
    return 0;
}

输出:

Enter 0-based index of desired Fibonacci Number: 6
Fibonacci number is: 8

分析:

函数 GetFibNumber()是在第 3~9 行定义的,这是一个递归函数,因为它在第 8 行调用了自己。第 5 和 6 行指定了退出条件,确保该函数在 fibIndex 小于 2 时不再递归。鉴于函数 GetFibNumber()调用自己时降低了 fibIndex 的值,因此递归到一定程度后将满足递归条件,从而停止递归,并将计算得到的斐波纳契数返回给 main()。

该文章会更新,欢迎大家批评指正。

推荐一个零声学院的C++服务器开发课程,个人觉得老师讲得不错,

分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,

fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,

TCP/IP,协程,DPDK等技术内容

点击立即学习:C/C++后台高级服务器课程

相关推荐
材料苦逼不会梦到计算机白富美2 小时前
贪心算法-区间问题 C++
java·c++·贪心算法
羚羊角uou3 小时前
【C++】list模拟实现(详解)
开发语言·c++
Peter_chq3 小时前
【计算机网络】多路转接之select
linux·c语言·开发语言·网络·c++·后端·select
翀哥~6 小时前
python VS c++
开发语言·c++·python
HABuo8 小时前
【数据结构与算法】合并链表、链表分割、链表回文结构
c语言·开发语言·数据结构·c++·学习·算法·链表
努力学习编程的伍大侠8 小时前
C++中的移动语义
开发语言·c++
奇妙之二进制8 小时前
2025年春招修订版《C/C++笔面试系列》(1) C语言经典笔面试题(上)
c语言·c++·面试
萱仔学习自我记录8 小时前
C++ 类和对象的定义涉及到的关键字记录
开发语言·c++
我不是程序猿儿8 小时前
【C++】友元friend的含义和用法
开发语言·c++