关于函数递归的基础

简介: 关于函数递归的基础

什么是递归

递归就是直接或者间接地调用自身,把一个大型复杂的程序简化为规模较小的程序,将大量的程序用简单的程序来代替。

递归的主旨是将大事化小

函数递归

在调用一个函数的过程中又出现直接或间接地调用该函数本身

C语言的特点之一就是允许函数的递归。

函数的限制条件

递归的实现需要2个必要条件

  • 递归存在限制条件,当满足这个限制条件,递归就不再继续
  • 每次递归之后要越来越接近这个限制条件。

举例讲解函数递归的实现

题目

有5个学生坐在一起,问第5个学生多少岁,他说比第4个学生大2岁。问第4个学生岁数,他说比第3个学生大2岁。问第3个学生,又说比第2个学生大2岁。问第2个学生,说比第1个学生大2岁。最后问第1个学生,他说是10岁。请问第5个学生多大。

题目分析

一共有5个学生,序号分别为1,2,3,4,5,第一个学生10岁,往后的每个学生都比前一个学生大两岁。

思路分析

非递归:

想要算出第五个学生的岁数,就是

第二个学生:10+2=12

第三个学生:12+2=14

第四个学生:12+2=16

第五个学生:16+2=18

递归:

我们要创建的函数:int age(int n), n就是我们要求的第五个学生的序号,到时候n=5即可。

age(5)=age(4)+2

age(4)=age(3)+2

age(3)=age(2)+2

age(2)=age(1)+2

效果等同于:age(n) = age(n-1)+2,输入:n=5

实现代码:

第一次以 n=5 进去,c=age(5-1)+2 -> c=age(4)+2,再次调用age函数,参数是4,

age(4)的返回值为c,c=age(4-1)+2-> c=age(3)+2,再次调用age函数,参数是3,

直到运行到age(1),age(1)=10,递推结束。

int age(int n)//5作为参数进来,n=5
{
    int c = 0;
    if(n==1)
        c = 10;
    else
        c=age(n-1)+2;//c=age(4)+2 这里age(4)参数为4,再次进入到 age 函数。
                     //函数age(4)又会走到这里,n=4,这里c=age(3)+2.
                     //c是函数的返回值,
    return (c);
}

限制条件:

n=1

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

我们的函数递归如果没有限制条件,就会陷入死循环

所以当n=1的时候,age(1)=10,就不会再执行递归c=age(n-1)+2

题目

用递归的方法求n!

题目分析

一个正整数的阶乘factorial)是所有小于及等于该数的正整数,并且0的阶乘为1。自然数n的阶乘写作n!。

思路分析

5!=5x4x3x2x1

4!=4x3x2x1

3!=3x2x1

……

我们发现5!=5x4!

4!=4x3!

因此得出n!=nx(n-1)!

实现代码:

#include <stdio.h>
int fact(int n)
{
    if(n==1)
        return 1;
    else
        return n*fact(n-1);
}
int main()
{
    int n = 0;
    scanf("%d",&n);
    int c = fact(n);
    printf("%d",c);
    return 0;
}

函数递归所引发的栈溢出问题

每一次函数的调用,都会向内存栈区申请空间,直到函数返回值,开始释放空间

这块空间主要是用来存放函数中的局部变量,和函数调用过程中上下文的信息

我们把这块空间叫做函数栈帧空间

我们留给函数栈帧的空间是有限的,所以函数递归有要求:

1.限制条件

2.越来越接近我们的限制条件

不然,无限地开辟函数栈帧空间,导致的栈溢出问题

刚才我们的n的阶乘的题目,我将限制条件改为n=6,随之函数的运行,会离限制条件越来越远,在msvc编译器底下,好像并没有报错,最后以无结果的形式结束运行,应该是有优化。


总结

1.递归是什么?

2.递归的限制条件的要求

3.对题目运用递归的方式进行求解

4.栈溢出问题(为什么要有限制条件)

目录
相关文章
|
5月前
|
人工智能 IDE API
白板秒变IDE,草图直接生成可运行代码!Pad.ws:白板+代码编辑器深度结合,创意到实现无缝衔接
Pad.ws是一款创新的在线开发环境,将交互式白板与完整IDE工具深度结合,支持多人实时协作和多种编程语言,无需安装即可通过浏览器访问。
186 1
白板秒变IDE,草图直接生成可运行代码!Pad.ws:白板+代码编辑器深度结合,创意到实现无缝衔接
|
11月前
|
并行计算 JavaScript 前端开发
worker_threads 多线程
worker_threads 多线程
280 4
|
8月前
|
机器学习/深度学习 存储 算法
《匿名化技术:数据隐私与价值挖掘的平衡探索》
在数据驱动的时代,数据成为企业和组织的核心资产,匿名化技术作为保护数据隐私的重要手段备受关注。它通过去除或混淆个人身份信息,如数据脱敏、泛化和加密等方法,有效保护隐私。然而,匿名化可能影响数据的完整性和准确性,进而影响价值挖掘。为平衡隐私保护与数据利用,需明确使用目的、加强数据治理、创新技术应用,确保数据安全合规,推动数字经济健康发展。
444 30
|
9月前
|
SQL 安全 算法
网络安全之盾:漏洞防御与加密技术解析
在数字时代的浪潮中,网络安全和信息安全成为维护个人隐私和企业资产的重要防线。本文将深入探讨网络安全的薄弱环节—漏洞,并分析如何通过加密技术来加固这道防线。文章还将分享提升安全意识的重要性,以预防潜在的网络威胁,确保数据的安全与隐私。
183 2
|
10月前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
267 4
|
安全 开发者
在代码的海洋中航行:我的编程之旅
这是一篇个人的技术感悟文章,作者以自己的编程之旅为主线,分享了从初识编程到深入探索的心路历程。文章不仅记录了作者在学习编程过程中的挑战与成就,还提供了一些实用的学习建议和心得体会。这篇文章适合所有对编程感兴趣的人阅读,无论你是初学者还是有经验的开发者,都能从中获得启发和共鸣。
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之如何将STRING类型转换为DATETIME类型
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
237 1
|
12月前
|
大数据
用wordcloud搞词云,大数据词云,自定义图像
用wordcloud搞词云,大数据词云,自定义图像
|
存储 算法 调度
基于和声搜索算法(Harmony Search,HS)的机器设备工作最优调度方案求解matlab仿真
通过和声搜索算法(HS)实现多机器并行工作调度,以最小化任务完成时间。在MATLAB2022a环境下,不仅输出了工作调度甘特图,还展示了算法适应度值的收敛曲线。HS算法模拟音乐家即兴创作过程,随机生成初始解(和声库),并通过选择、微调生成新解,不断迭代直至获得最优调度方案。参数包括和声库大小、记忆考虑率、音调微调率及带宽。编码策略将任务与设备分配映射为和声,目标是最小化完成时间,同时确保满足各种约束条件。
|
存储 监控 Ubuntu
一键搞定:用脚本轻松部署ELK,让日志分析变得简单又高效
【8月更文挑战第13天】ELK栈由Elasticsearch、Logstash和Kibana组成,用于日志存储、解析及展示,是大数据领域广泛采用的日志解决方案。鉴于其安装配置复杂,本文提供了一个适用于Ubuntu 16.04的ELK自动安装Shell脚本示例。脚本首先确保Java环境安装,接着添加Elastic.co的APT仓库并安装ELK组件,最后启动所有服务。通过自动化流程,简化部署工作,减少人为错误,提升效率。实际应用中还需根据具体需求调整配置和服务设置。
389 0