感悟神奇的递归

本文介绍了递归的基本使用方法,包括递归的数学定义、在程序设计中的应用,以及三个递归示例:求和、斐波那契数列和字符串长度计算。此外,还探讨了如何建立递归模型,并以汉诺塔问题为例展示了递归的有趣应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、基本使用方法

  积累了一些学习笔记,温故而知新,同时与大家分享,后面会陆续整理出来,小白学习经验,欢迎大家轻拍。

  关于递归,我们高中数学就有接触,教材中是这样定义的:当一个函数用自身来定义时就称为递归。C++允许函数是递归的,但必须要记住,C++所做的仅仅是试图遵循递归思想,不是所有的数学递归函数都能被有效的C++的递归模拟来实现。要点在于,递归函数应该像非递归函数一样只用几行就能表示出来[1]。例如:

int f(int x)
{
    if(x == 0)
        return 0;
    else
        return 2 * f(x - 1) + x * x;
}
  • 1、递归是一种数学上的分而治之的思想
    a、将原问题分解为规模较小的问题进行处理。
    b、问题的分解是有限的。
    c、递归问题的一般表示法:
    f(n) ={
    anf(n1)a1n>1n==1an∪f(n−1)n>1a1n==1
  • 2、递归在程序设计中的应用
    a、函数体中存在自我调用的函数
    b、递归函数必须有递归出口(边界条件)
    c、函数的无限递归将导致程序的崩溃
  • 3、具体示例
    a、求和
    求解:Sum(n)=1+2+3…+n
    递归表示:

    Sum(n) = {

    n+Sum(n1)1n>1n==1n+Sum(n−1)n>11n==1

    C++代码如下:
#include <iostream>
unsigned int sum(unsigned int n)
{
    if(n > 1)
    {
        return n + sum(n-1);
    }
    else
    {
        return 1;
    }
}
int main()
{
    cout << sum(100) << endl;
    return 0;
}

b、斐波那契数列
数列自身递归定义:1,1,2,3,5,8,13,21…
函数表示递归:

fac(n) ={

fac(n1)+fac(n2)11n>=3n==2n==1fac(n−1)+fac(n−2)n>=31n==21n==1

C++代码:
#include <iostream>
unsigned int fac(unsigned int n)
{
    if(n > 2)
    {
        return fac(n-1) + fac(n-2);
    }
    if((n == 2) || (n == 1))
    {
        return 1;
    }
    return 0;
}
int main()
{
    for(int i=1; i <= 10; i++)
    {
        cout << i << ":" << fac(i) << endl;
    }
    return 0;
}

c、用递归方法编写函数求字符串的长度
C++具体代码

#include <iostream>
unsigned int _strlen_(char *s)  //避免与库函数重名
{
    if(*s != '\0')
    {
        return 1 + _strlen_(s+1);
    }
    if(*s == '\0')
    {
        return 0;
    }
    return 0;
    //上述代码的另一种写法:return s ? (*s ? (1 + _strlen_(s+1)) : 0) : 0;
}
int main()
{
    cout << _strlen_("Hello优快云er!") << endl;
    return 0;
}

上述三个示例的结果如图:
这里写图片描述

注意事项:
  解决问题的核心是如何建立递归模型,注意切勿陷入递归函数的执行细节上,学会通过程序描述问题,还要注意递归解法必须有出口,也即边界,否则无解。出口的概念我们可以这样解释:总有某些基准的情形,它们不用递归就能求解。还有一个准则需要注意,对于那些要被求解的情形,递归调用必须总能够朝着一个基准推进。

二、有趣的实例

我们来看看有趣的汉诺塔问题
这里写图片描述

实现代码:

#include <iostream>
using namespace std;
void HanoiTower(int n, char a, char b, char c)
{
    if(n == 1)
    {
        cout << a << "-->" << c << endl;
    }
    else
    {
        HanoiTower(n-1, a, c, b);
        HanoiTower(1, a, b, c);
        HanoiTower(n-1, b, a, c);
    }
}

//测试
int main()
{
    HanoiTower(3, 'a', 'b', 'c');
    return 0;
}

方案如下图:
这里写图片描述
这里面的a、b、c分别代表三个柱子,箭头表示木块移动的方向。以3层塔的实验结果与手推一致,更多层塔等你去试哦!

参考文献
[1] Mark Allen Weiss,Data Structures and Algorithm Analysis in C++ Third Edition,2011.08

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值