*深入学习函数(3)-- 递归篇(图文详解)
创始人
2024-04-09 03:34:26
0

目录

一、什么是递归

                 推荐两个问答社区网站

二、递归的两个必要条件

三、递归练习

                1、接收一个整型值(无符号),按照顺打印它的每一位。输入:1234,输出:1 2 3 4

                2、编写函数不允许创建临时变量,求字符串长度。

四、迭代以及练习

               1、求n的阶乘(不考虑溢出)

               2、求第n个斐波那契数(不考虑溢出)


一、什么是递归

●程序调用自身的编程技巧称为递归。

●递归作为一种算法在程序设计语言中广泛应用,一个过程或函数在其定义或说明中直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相识的规模较小的问题来求解

●只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量

递归的主要思考方式在于:把大事化小。

 为了了解递归,首先写一个史上最简单的递归(会发生错误的递归):

main函数在自己调用自己。但调用着就会发现,程序崩了,它不会一直死递归下去。

同样可以按F10来观察程序

接下来程序就会弹出下面的窗口,stack overflow:栈溢出。这就要牵扯到内存中的栈区、堆区和静态区了。(https://mp.csdn.net/mp_blog/creation/editor/127569715)以往的博客中有细讲

每调用函数,都会为本次函数,在内存的栈区上开辟一块内存空间。

接下来回到刚刚的代码,每调用一次main函数就会在栈区开辟一块内存空间,一直开辟总会有一天把栈区给“榨干”了,这时栈就溢出了。

推荐两个问答社区网站

①(https://stackoverflow.cn/zh-cn)这个网站(国外)相当于一个程序员的问答社区。

②下面的网站叫思否是国内的程序员问答社区
https://segmentfault.com/?u_atoken=f4253b51-aefc-4b63-98f8-9bacecbcd37c&u_asession=01_D58mDxSPeHosldc992SW2dJSe7g4tAfNZtBCDZRWaInKuo59MObn0WcP16k9557X0KNBwm7Lovlpxjd_P_q4JsKWYrT3W_NKPr8w6oU7K9DdwtExMAxsSKcUExmJItvUe3R9QHfzEvknA4dzJmVTGBkFo3NEHBv0PZUm6pbxQU&u_asig=056DBa8BrmTjQT3vz1WFh7_n4TIhIKnCPK8XlNkwPwQB9tVM5jSJ5sVSU-bud6wg3z3v3gBPgQRYOOo0Ag3z7K39D3q3uS2zwSow-0XUFj1eCFpve4R8muC2gXrc4ZShzBH9gxVvi8KyRYwXPTkFBwfb4B0WqgQLp3TT0KCgfA9Cv9JS7q8ZD7Xtz2Ly-b0kmuyAKRFSVJkkdwVUnyHAIJzUNFYcC8iEgq-ihrSinwhXI2Ef-I9PryqZW8BslxiTZDH_8T8uYGNepqxdb-gLe1IO3h9VXwMyh6PgyDIVSG1W9ss1nde6qsjCMZiNfYNgVU6rN4WnkP27a0CQVvwR6dMoVdQ7neKOwcVaOWd5tOnCj9Mmq7zBlclDEIHdVheGprmWspDxyAEEo4kbsryBKb9Q&u_aref=LM2U0pesUMjVOH3Sz9bMZji4E8Y%3Dhttps://segmentfault.com/?u_atoken=f4253b51-aefc-4b63-98f8-9bacecbcd37c&u_asession=01_D58mDxSPeHosldc992SW2dJSe7g4tAfNZtBCDZRWaInKuo59MObn0WcP16k9557X0KNBwm7Lovlpxjd_P_q4JsKWYrT3W_NKPr8w6oU7K9DdwtExMAxsSKcUExmJItvUe3R9QHfzEvknA4dzJmVTGBkFo3NEHBv0PZUm6pbxQU&u_asig=056DBa8BrmTjQT3vz1WFh7_n4TIhIKnCPK8XlNkwPwQB9tVM5jSJ5sVSU-bud6wg3z3v3gBPgQRYOOo0Ag3z7K39D3q3uS2zwSow-0XUFj1eCFpve4R8muC2gXrc4ZShzBH9gxVvi8KyRYwXPTkFBwfb4B0WqgQLp3TT0KCgfA9Cv9JS7q8ZD7Xtz2Ly-b0kmuyAKRFSVJkkdwVUnyHAIJzUNFYcC8iEgq-ihrSinwhXI2Ef-I9PryqZW8BslxiTZDH_8T8uYGNepqxdb-gLe1IO3h9VXwMyh6PgyDIVSG1W9ss1nde6qsjCMZiNfYNgVU6rN4WnkP27a0CQVvwR6dMoVdQ7neKOwcVaOWd5tOnCj9Mmq7zBlclDEIHdVheGprmWspDxyAEEo4kbsryBKb9Q&u_aref=LM2U0pesUMjVOH3Sz9bMZji4E8Y%3D

二、递归的两个必要条件

●存在限制条件,当满足这个限制条件的时候,递归便不再继续。

●每次递归调用之后就会越来越接近这个限制条件

三、递归练习

1、接收一个整型值(无符号),按照顺打印它的每一位。输入:1234,输出:1 2 3 4

解题思路: 

代码实现:

#include 
void Print(unsigned int x)
{if (x > 9)  //判断两位数{Print(x/10);}printf("%d ", x % 10);
}int main()
{unsigned int  num = 0;scanf("%u", &num);//%u - 输入无符号值//写一个函数打印num的每一位Print(num);return 0;
}

画图解释递归:

首先大家要知道,递归其实是两个词,递:递推,归:回归。(很重要!!!)

先递推(黑色),后回归(红色)

2、编写函数不允许创建临时变量,求字符串长度。

首先运行创建临时变量的话,我们应该怎么写呢?

#include 
int ch_len(char* arr)
{int count = 0;//计时器while (*arr != '\0'){count++;arr++;}return count;
}int main()
{char arr[] = "hello";int ret = ch_len(arr);printf("%d\n",ret);
}

代码详解:

 那不允许创建临时变量该怎么写呢?既然讲到了递归,就得用递归来解决

解题思路:

求ch_len(“hello”),如果第一个字符不是'\0',是不是就能转化成1+ch_len(“ello”),接下来ch_len(“ello”)的第一个字符又不是'\0',是不是又能转化成1+1+ch_len(“llo”),接下来以此类推直到'\0'。

代码实现:

int ch_len(char* arr)
{if (*arr != '\0')return 1 + ch_len(arr + 1);elsereturn 0;//当碰上第一个字符为\0,就返回0;
}
int main()
{char arr[] = "hello";int ret = ch_len(arr);printf("%d\n",ret);
}

画图解释递归:

先递推(黑色),后回归(红色)

 最后返回了5。

画图不易,请谅解。

如果没看懂后期还会出一个递归的练习。

四、迭代及练习

所谓迭代,就是用非递归来解决问题。 

循环也是一种迭代。

1、求n的阶乘(不考虑溢出)

解题思路:

首先看看递归实现

代码实现:

#include 
int Fac(int n) //形参的名字可以和实参一样
{if (n <= 1){return 1;}else{return n * Fac(n - 1);}
}
int main()
{int n = 0;//输入n的值scanf("%d", &n);int ret = Fac(n);printf("%d\n", ret);return 0;
}

老样子,我们画图来分析递归,

递推(黑),回归(红)

 迭代(循环)

#include 
int Fac(int n) 
{int i = 0;int ret = 1;for (i = 1; i <= n; i++){ret = ret * i;}return ret;
}
int main()
{int n = 0;//输入n的值scanf("%d", &n);int ret = Fac(n);printf("%d\n", ret);return 0;
}

2、求第n个斐波那契数(不考虑溢出)

解题思路:

再来看看递归实现

代码实现:

#include 
int Fib(int n)
{if (n <= 2){return 1;}else{return Fib(n-1) + Fib(n - 2);}
}
int main()
{int n = 0;//输入n的值scanf("%d", &n);int ret = Fib(n);printf("%d\n", ret);return 0;
}

 画图解析:

递推(黑),回归(红)

 实际上,当输入50时,编辑器的光标还在闪烁,有的人可能会认为程序挂掉了,其实并没有,程序此时此刻还在长时间计算第50个斐波那契数。

所以这题使用递归还存在局限性,那么接下来我们来尝试迭代(循环)

解题思路:

 代码实现:

#include 
int Fib(int n)
{int a = 1;int b = 1;int c = 1;while (n>2) //当n = 1或者2时可以不用算,因为结果都是1,{c = a + b;a = b;b = c;n--;}return c;
}
int main()
{int n = 0;//输入n的值scanf("%d", &n);int ret = Fib(n);printf("%d\n", ret);return 0;
}

相关内容

热门资讯

凯撒同盛发展股份有限公司关于公... 本公司及董事会全体成员保证信息披露的内容真实、准确、完整,没有虚假记载、误导性陈述或重大遗漏。 近日...
大金重工股份有限公司 关于诉讼... 本公司及董事会全体成员保证信息披露的内容真实、准确、完整,没有虚假记载、误导性陈述或重大遗漏。 特别...
政策合力落地 中国经济加速孕育... 证券时报记者 胡飞军 近日,在中央经济工作会议部署2026年经济工作、政策方向,以及美国美联储技术性...
律师写公众号:流量和成案是两回... 今年写公众号,丢掉之前营销老师的讲的套路,按照自己的想法输出,没想流量的事,流量反而多起来了。按照很...
吉林泉阳泉股份有限公司 关于前... 证券代码:600189 证券简称:泉阳泉 公告编号:2025一074 吉林泉阳泉股份有限公司 关于前...
明年居民增收重在稳就业 专家建... 证券时报记者 贺觉渊 《中共中央关于制定国民经济和社会发展第十五个五年规划的建议》明确提出“实施城乡...
云南南天电子信息产业股份有限公... 本公司及董事会全体成员保证信息披露内容的真实、准确、完整,没有虚假记载、误导性陈述或重大遗漏。 重要...
拉加德暗示欧央行不急行动:政策... 在欧洲央行连续第四次会议维持利率不变且上调今明后三年经济增长预期后,欧央行行长拉加德重申央行在利率政...
连接场景、连接政策、连接市场:... 近日,国务院常务会议专门部署“增强消费品供需适配性,进一步促进消费政策措施”,强调要以消费升级引领产...
美盈森(002303)披露控股... 截至2025年12月18日收盘,美盈森(002303)报收于3.91元,较前一交易日上涨0.26%,...