函数递归超详解!

news2024/11/15 17:32:39

目录

 1.什么是递归调用?

直接调用

         间接调用

2.什么是递归?

3.递归举例

3.1求n!的阶乘

3.1.1.非递归法

3.1.2.递归法

3.1.2.1分析和代码实现

3.2顺序打印一个整数的每一位

3.2.1分析和代码实现

4.递归与迭代

4.1举例:斐波那契数列

4.1.1迭代法

4.1.2递归法


 1.什么是递归调用?

在调用一个函数出现直接间接地调用该函数本身,称为函数的递归调用

直接调用

void f()
{
...
...
f();//调用语句
...
}

间接调用

(下面这个代码中f函数调用了g函数,g函数又调用了f函数)

void f()
{
...
...
g();//调用g函数
...
}
void g()
{
...
...
f();//调用f函数
...
}

从以上两个函数可以看到,这两种递归调用都是无终止的自身调用。显然,程序中不应该出现这种无终止的递归调用,而只应该出现有限次数的、有终止的递归调用,这可以用if语句来控制,只有在某一条件成立时才继续执行递归调用;否则就不在继续。

2.什么是递归?

递归中的递就是递推,归就是回归

3.递归举例

3.1求n!的阶乘

3.1.1.非递归法

在进入递归之前,先体会一下非递归法

#include<stdio.h>
int   fac (int  n)   //n为形参
{  
    int i,m=1;
    for(i=1;i<=n;i++)
    {
        m=m*i; //用循环累乘:m=1*2*...*n
    }
   return m;
}
int  main()
{
    int n,y;
    scanf("%d",&n);//输入n
    y=fac(n);//n为实参
	printf("%d!=%d",n,y);
return 0;
}

(注:实参和形参可以重名,如果主程序中输入n值是4,调用函数时,则是把其值4传递给函数的形式参数n,形参n的值即为4,实参仅是做的一个值的传递,这个过程与实参的名字是什么无关,所以形参和形参名字相同不影响传值调用

3.1.2.递归法
3.1.2.1分析和代码实现

n!=n*(n-1)!

4!=4*3*2*1

3!=3*2*1

所以:4!=4*3!

 

当n==0的时候,阶乘为1,其余用公式计算

先将整体代码列给大家

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

下面用n=5时的例子给大家解释

fact(5)虽然=5*fact(4),但是fact(4)又是一个调用函数,再次调用fact函数,然后求得fact(4)为多少后,别忘记乘上前面的5,也可按照上图一步一步算

因为你调用完得出的值得返回去

递归是用少量的代码完成大量复杂的运算 

3.2顺序打印一个整数的每一位

分析:输入一个整数,按照顺序打印一个整数的每一位

eg:

输入:1234 输出:1 2 3 4

3.2.1分析和代码实现

1234

1234%10=4

1234/10=123

123%10=3

123/10=12

12%10=2

12/10=1

1%10=1

1/10=0

以上的方法很容易理解,但是过于复杂,所以下面我们用递归的方法解决此问题

 

仔细分析上图解析,可以的得出此代码为

#include<stdio.h>
void print(int n)
{
	if (n > 9)
		print(n / 10);
	printf("%d ", n % 10);
}
int main()
{
	int n = 0;
	scanf_s("%d", &n);
	print(n);
	return 0;
}

4.递归与迭代

fact函数是可以产生正确的结果,但是在递归函数中涉及一些运行时的开销。

在c语言中每一次函数调用,都需要为本次函数调用在内存的栈区申请一块内存空间来保存函数调用期间的各种局部变量的值,这块空间被称为运行时堆栈,或者函数栈帧

函数不返回,函数对应的栈帧空间就一直占用,所以函数调用中存在递归调用的话,每一次递归调用都会开辟属于自己的栈帧空间,直到函数递归不再继续,开始回归,开始回归,才逐层释放栈帧空间。

所以如果采用函数递归的方式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出的问题。

 

所以我们可以使用迭代的方法(循环) 

 

#include<stdio.h>
int fact(int n)
{
	int i = 0;
	int ret = 1;
	for (i = 1; i <= n; i++)
	{
		ret *= i;
	}
	return ret;
}
int main()
{
	int n = 0;
	scanf_s("%d", &n);
	int r = fact(n);
	printf("%d", r);
	return 0;
}

注:当一个问题非常复杂,难以用迭代的方法实现时,此时递归实现的简洁性便可以补偿它所带来的开销。

4.1举例:斐波那契数列
4.1.1迭代法
#include<stdio.h>
int fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 1;
	while (n > 2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}

int main()
{
	int n = 0;
	scanf_s("%d", &n);
	int r=fib(n);
	printf("%d\n", r);
	return 0;
}
4.1.2递归法
#include<stdio.h>
int count = 0;
int fib(int n)
{
	if (n == 3)
		count++;

	if (n <= 2)
		return 1;
	else
		return fib(n - 1) + fib(n - 2);
}
int main()
{
	int n = 0;
	scanf_s("%d", &n);
	int r=fib(n);
	printf("%d\n", r);
	printf("%d", count);
	return 0;
}

注意:此题使用迭代法(非递归法)更好,因为递归法计算时,会有重复计算, 下图我们看到,

在计算第40个斐波那契数列时,第三个斐波那契数被重复计算了39088169次,这就会非常复杂。

而用迭代是,从小往大加就行了。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1974048.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开放式耳机更适合运动的时候使用?开放式耳机推荐指南

开放式耳机确实非常适合运动时使用&#xff0c;原因主要有以下几点。 首先&#xff0c;保持对外界的感知是很重要的一点。在运动的时候&#xff0c;我们需要听到周围的环境声音&#xff0c;比如车辆的行驶声、行人的呼喊等&#xff0c;以便及时做出反应&#xff0c;保证自身安全…

【MySQL】索引概念解析

1.什么是索引&#xff1f; MySQL中的索引是一种数据结构&#xff0c;用于帮助MySQL数据库管理系统快速查询数据。索引的主要目的是提高数据检索的速度&#xff0c;减少数据库系统需要扫描的数据量。 优点&#xff1a; 索引可以极大的提高数据检索效率&#xff0c;降低数据库…

【Nuxt】配置

Nuxt 配置 nuxt.config.ts 里面可以添加相关配置&#xff1a; runtimeConfig 运行时配置。 // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({compatibilityDate: 2024-04-03,devtools: {enabled: true},runtimeConfig: {appKey: …

手拉手模型笔记and一线三角笔记

手拉手模型 基本需要&#xff1a;两个 顶角相等 的 等腰 三角形 共 顶点 反手拉手: 等边 等腰 R t △ 等边\\等腰Rt△ 等边等腰Rt△ 左手拉左手&#xff0c;右手拉右手( − 红线 − \textcolor{red}{-红线-} −红线−): △ A B D ≅ △ A C E ( S A S ) △ABD \cong △ACE(S…

一次多波束和浅地层处理的经历—信标机出问题?

最近处理多波束和浅地层时&#xff0c;一个从来没有过的问题出现了。 多波束数据(.pds)是由PDS2000采集的&#xff0c;使用设备型号为T50P。浅地层数据(.raw)是有SESWIN采集的&#xff0c;使用设备型号为SES2000 Standard。 1、多波束处理 多波束数据采用CARIS11.3处理的。船…

返校季热度持续发酵,赛盈分销浅谈下半年选品趋势!

小孩学习用的东西&#xff0c;那可真是省不了一点&#xff0c;该买的&#xff0c;家长还是会买。 特别是在每年的7-9月份正是海外返校季高消费的时候&#xff0c;这也是卖家少有的能在淡季里血赚的机会了。 都说早起的鸟儿有虫吃&#xff0c;一些朋友提前行动的&#xff0c;已经…

day17 Java流程控制——用户交互Scanner

day17 Java流程控制——用户交互Scanner 目录 day17 Java流程控制——用户交互Scanner1. 什么是Scanner对象&#xff1f;2. 实操 1. 什么是Scanner对象&#xff1f; Scanner对象是Java编程语言中的一个类&#xff0c;存在于java.util包中。它用于获取输入&#xff0c;可以是各…

数据库的安装初始化及管理

1. 官网下载或者 wget [rootmysql ~] # ls anaconda-ks.cfg initserver.sh mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar mysql-community-client-8.0.33-1.el7.x86_64.rpm mysql-community-client-plugins-8.0.33-1.el7.x86_64.rpm mysql-community-common-8.0.33-1.el7.…

大数据-57 Kafka 高级特性 消息发送相关01-基本流程与原理剖析

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

反转链表~

一&#xff1a;初始化 public class ListNode {public int val;public ListNode next;public ListNode(int val,ListNode next){this.val val;this.next next;}Overridepublic String toString(){StringBuilder sb new StringBuilder(64);sb.append("[");ListNod…

【系统架构设计师】二十四、安全架构设计理论与实践①

目录 一、安全架构概述 1.1 信息安全面临的威胁 1.1.1 安全威胁分类 1.1.2 常见的安全威胁 1.2 安全架构的定义和范围 二、安全模型 2.1 状态机模型 2.2 Bell-LaPadula模型 2.3 Biba模型 2.4 Clark-Wilson模型 2.5 Chinese Wall 模型 往期推荐 一、安全架构概述 1…

vue3+vue-simple-uploader +SpringBoot实现大文件分块上传

效果图 一、安装所需依赖包 npm install vue-simple-uploadernext --savenpm install spark-md5 --save二、main.ts 注册组件 import { createApp } from vue import uploader from vue-simple-uploader import vue-simple-uploader/dist/style.css import App from ./App.vu…

Java ArrayList源码阅读笔记(基于JDK17)

Java ArrayList源码阅读笔记&#xff08;基于JDK17&#xff09; 虽然不喜欢看源码&#xff0c;但是据说会让人变强啊&#xff0c;看别的大佬的代码也许才知道怎么处理自己的一坨吧&#xff0c;因此冒着秃顶的风险还是来看看吧。。。 第一遍先简单看看吧&#xff0c;搞不清楚的…

双阈值最大最小值筛选

问题&#xff1a; 如下图所示的问题&#xff0c;给定最小阈值、最大阈值以及一段数据队列&#xff0c;对数据队列中超过阈值部分的极值进行保存&#xff0c;即从队列中得到P1-P6 计算规则 规则类似状态机 首先定义last_type标志位&#xff1a; { 上一时刻大于 m a x _ t h…

win7安装mysql-installer-community-8.0.11.0

1、安装Microsoft Visual C 2019 Redistributable Package (x64) 官网下载地址&#xff1a;https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?viewmsvc-160#latest-microsoft-visual-c-redistributable-version 通过百度网盘分享的文件&#xff1…

VBA_MF系列技术资料1-680

MF系列VBA技术资料1-680 WORD 目录下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/17TrFO37OgnjiwvACvMna_A?pwdbr3g 提取码&#xff1a;br3g 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧&#xff0c;我参考大量的资料&#xff…

大数据-63 Kafka 高级特性 分区 副本机制 宕机恢复 Leader选举

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

【全国大学生电子设计竞赛】2022年D题

&#x1f970;&#x1f970;全国大学生电子设计大赛学习资料专栏已开启&#xff0c;限时免费&#xff0c;速速收藏~

详解Xilinx FPGA高速串行收发器GTX/GTP(2)--什么是GTX?

GTX本质上是基于SerDes技术的高速串行收发器,它是FPGA内部的底层电路,也叫做Gigabit Transceiver(吉比特收发器,简称为GT)。其中A7系列使用的GT叫GTP,K7系列使用的GT叫GTX,V7系列使用的GT叫GTH和GTZ,它们的结构大致相同,但是线速率的关系是 GTZ>GTH>GTX>GTP,…

Android进程保活:如何让app一直运行

目录 1&#xff09;为什么需要进行进程保活呢&#xff1f;需求是什么&#xff1f; 2&#xff09;进程分类 3&#xff09;进程的优先级 4&#xff09;如何提高进程优先级 5&#xff09;如何进行进程保活 一、为什么需要进行进程保活呢&#xff1f;需求是什么&#xff1f; 比如…