递归 落日映苍穹つ 2022-01-13 18:21 195阅读 0赞 1、递归 函数的递归调用; fun1()-->fun2()-->fun3()-->fun1() 间接递归 fun1()<-->fun1() 直接递归 2、递归调用的性质特点 (1)、函数的调用存在系统资源的消耗,空间及时间的消耗; (2)、函数的递归调用往往都比较深,因此会产生大量的系统资源的消耗; (3)、函数的递归调用,若不注意调用的规模(即深度),很容易造成系统资源不足时崩溃的结果; (4)、递归调用比较符合数学递归定义,因此递归程序都比较好被证明相关算法的正确性及完备性; (5)、可以先通过递归算法验证程序,在转换成非递归算法以保证效率和安全; 3、递归调用的模型图 **每次都得进行形参压栈,保存现场信息,此时变量名称相同,但是已经是在不同的函数中,具有不同的生命周期;** 模型图: [![wKioL1gxEpqB8AHEAAAcY\_tePyY524.png-wh\_50][wKioL1gxEpqB8AHEAAAcY_tePyY524.png-wh_50]][wKioL1gxEpqB8AHEAAAcY_tePyY524.png-wh_50] 4、递归程序的设计思路 **(1)、首先要写出递归的结束条件;** **(2)、其次先只想当前的递归程序该怎么操作(不要去想上一次/下一次的递归),并写出有效代码;** **(3)、然后在着重考虑与下一次在调用上的递进关系,此时通过参数加以实现;** 5、递归程序示例 (1)、汉诺塔问题 4层汉诺塔的搬移问题: 代码如下: #include<stdio.h> void Hanoii(int n, char s, char a, char t); void Hanoii(int n, char s, char a, char t) { if(n > 0) { Hanoii(n-1, s, t, a); printf("%d : %c -> %c\n", n, s, t); Hanoii(n-1, a, s, t); } } void main(void) { Hanoii(4, 'A', 'B', 'C'); } 运行结果: **[![wKiom1gxFnqRuSGlAABFb52Iu7I133.png-wh\_50][wKiom1gxFnqRuSGlAABFb52Iu7I133.png-wh_50]][wKiom1gxFnqRuSGlAABFb52Iu7I133.png-wh_50]** (2)、字符串转置 解法一:非递归 代码如下: #include<stdio.h> #include<string.h> void strrev(char *str); void strrev(char *str){ char *p; char *q; int length = strlen(str); int tmp; p = str; q = str+length-1; while(p < q){ tmp = *p; *p = *q; *q = tmp; p++; q--; } } int main(void){ char str[] = "abcdefg"; printf("逆序前:%s\n", str); strrev(str); printf("逆序后:%s\n", str); } 运行结果: [![wKiom1gxF8-BkljHAAAuJAio36k650.png-wh\_50][wKiom1gxF8-BkljHAAAuJAio36k650.png-wh_50]][wKiom1gxF8-BkljHAAAuJAio36k650.png-wh_50] 解法二:递归 代码如下: #include<stdio.h> #include<string.h> void strrev_1(char *str, int length); void strrev_1(char *str, int length){ char tmp; if(length > 1){ tmp = *str; *str = *(str+length-1); *(str+length-1) = tmp; strrev_1(str+1, length-2); } } int main(void){ char str[] = "abcdefg"; int length = strlen(str); printf("逆序前:%s\n", str); strrev_1(str, length); printf("逆序后:%s\n", str); return 0; } 运行结果: [![wKioL1gxGHqCoNRvAAAwcYR8j2U974.png-wh\_50][wKioL1gxGHqCoNRvAAAwcYR8j2U974.png-wh_50]][wKioL1gxGHqCoNRvAAAwcYR8j2U974.png-wh_50] 解法三:递归 代码如下: #include<stdio.h> #include<string.h> void revStr(char *str, char *tmp); void revStr(char *str, char *tmp){ if(str == NULL || tmp == NULL){ printf("有为空的,逆序不能进行\n"); return; } if(*str == 0){ return; } revStr(str+1, tmp); //用栈实现字符串的逆序,先进后出; strncat(tmp, str, 1); } int main(void){ char str1[80] = "abcdefghijkl"; char tmp[80]; printf("逆序前:%s\n", str1); revStr(str1, tmp); printf("逆序后:%s\n", tmp); } 运行结果: [![wKiom1gxGbTyEIj\_AAAyHSm759U759.png-wh\_50][wKiom1gxGbTyEIj_AAAyHSm759U759.png-wh_50]][wKiom1gxGbTyEIj_AAAyHSm759U759.png-wh_50] 转载于:https://blog.51cto.com/wait0804/1874723 [wKioL1gxEpqB8AHEAAAcY_tePyY524.png-wh_50]: /images/20220113/54a6ac53d1af4a12858661e8473d5c0a.png [wKiom1gxFnqRuSGlAABFb52Iu7I133.png-wh_50]: https://s1.51cto.com/wyfs02/M00/8A/76/wKiom1gxFnqRuSGlAABFb52Iu7I133.png-wh_500x0-wm_3-wmp_4-s_644599905.png [wKiom1gxF8-BkljHAAAuJAio36k650.png-wh_50]: https://s1.51cto.com/wyfs02/M01/8A/76/wKiom1gxF8-BkljHAAAuJAio36k650.png-wh_500x0-wm_3-wmp_4-s_1480229270.png [wKioL1gxGHqCoNRvAAAwcYR8j2U974.png-wh_50]: /images/20220113/b89bedc3c174415391daa1b2fdf85a81.png [wKiom1gxGbTyEIj_AAAyHSm759U759.png-wh_50]: https://s1.51cto.com/wyfs02/M02/8A/76/wKiom1gxGbTyEIj_AAAyHSm759U759.png-wh_500x0-wm_3-wmp_4-s_828611019.png
相关 递归 递归算法基本思想:找出递归子结构性质(原问题的解包含了子问题的解)、用子问题的解来递归定义原问题的解、找出递归终止条件。 示例: 例1 阶乘函数 阶乘函数可 ╰半橙微兮°/ 2022年06月09日 09:14/ 0 赞/ 246 阅读
相关 递归 > 递归的定义其实很简单,无非就是函数自己调用自己,但是要注意递归函数一定要有终止的条件,因为如果无限次调用而无法结束就会导致内存耗尽,系统就崩了…… 下面,主要利用递归实现 ╰+攻爆jí腚メ/ 2022年06月06日 11:37/ 0 赞/ 188 阅读
相关 递归——线性递归与二分递归 递归 线性递归 例子1:数组求和 int sum( int A[], int n) { //数组求和算法:线性递归版 if 向右看齐/ 2022年05月21日 04:41/ 0 赞/ 296 阅读
相关 递归 递归优点:代码简单 代码量少 递归缺点:不易理解 用递归解决问题时,主要思路: 1.将一个大问题分解成子问题 2.子问题除了问题规模会变小,和原问题解决的思路是一 向右看齐/ 2022年05月03日 10:28/ 0 赞/ 184 阅读
相关 递归 1. public class HelloWorld \{ 2. public static void main(String\[\] args)\{ 3. // Sca 女爷i/ 2022年04月12日 10:50/ 0 赞/ 286 阅读
相关 递归 递归Recursion 递归要求 1. 递归一定要有退出条件,递归调用一定要执行到这个退出条件。没有退出条件的递归调用,就是无限调用 2 雨点打透心脏的1/2处/ 2022年02月19日 05:39/ 0 赞/ 258 阅读
相关 递归 1、递归 函数的递归调用; fun1()-->fun2()-->fun3()-->fun1() 间接递归 fun1()<-->fun1() 直接递归 2、递归 落日映苍穹つ/ 2022年01月13日 18:21/ 0 赞/ 196 阅读
相关 递归 问题描述 任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。 将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:13 冷不防/ 2021年12月24日 08:43/ 0 赞/ 272 阅读
相关 递归 递归 递归就是一个函数直接或间接的调用自己.一般来说,递归需要有边界条件,递归前进段和递归返回段.当边界条件不满足的时,递归前进,当边界条件满足的时候,递归返回. 递归就 ﹏ヽ暗。殇╰゛Y/ 2021年12月12日 06:53/ 0 赞/ 206 阅读
相关 递归 递归只是让你解决方案更加清晰,并没有性能上的优势。实际上,在有些情况下,使用循环的性能更好。正如,在Stack Overflow 上,Leigh Caldwell 说了一句话: 男娘i/ 2021年09月13日 23:58/ 0 赞/ 330 阅读
还没有评论,来说两句吧...