一 递归是什么?
1定义:递归即递推和回归,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。
2优点:可以把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较⼩的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化⼩的过程。
#include <stdio.h>
int main (){printf ( "hehe\n" );main(); //main 函数中⼜调⽤了 main 函数return 0 ;}
上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演⽰递归的基本式,不是为了解决问 题,代码最终也会陷⼊死递归,导致栈溢出(Stack overflow)。那玩什么会出现栈溢呢?这是因为代码运行会向内存申请空间,而死递归导致向内存申请空间超过导致栈溢出。
二 递归的限制条件
但是满足上面二个条件不一定是递归,但不满足上面二个条件一定不是递归。
三 递归的举例
1 求n的阶乘
计算n的阶乘(不考虑溢出),n的阶乘就是1~n的数字累积相乘。
1.1分析和代码实现
5 ! = 5 * 4 * 3 * 2 * 14 ! = 4 * 3 * 2 * 1
n的阶乘的公式: n! =n*n-1*n-2......*1= n ∗ (n − 1)!
这样就能写出 n 的阶乘的递归公式
(1)n=0: fac(n)=1
(2)n>1: fac(n)=n*fac(n-1)//fac(n)表示n的阶乘
# include <stdio.h>int Fact ( int n){if (n== 0 )return 1 ;elsereturn n*Fact(n -1 );}
int main (){int n = 0 ;scanf ( "%d" , &n);int ret = Fact(n);printf ( "%d\n" , ret);return 0 ;}


2 举例2:顺序打印⼀个整数的每⼀位
Print( 1234 )==>Print( 123 ) + printf ( 4 )==>Print( 12 ) + printf ( 3 )==>Print( 1 ) + printf ( 2 )==> printf(1)
void Print ( int n){if (n> 9 ){Print(n/ 10 );}printf ( "%d " , n% 10 );}int main (){int m = 0 ;scanf ( "%d" , &m);Print(m);return 0 ;}
2.3画图推演
或
四 递归与迭代
1递归的好与坏;好处:是⼀种很好的编程技巧,但是和很多技巧⼀样可以把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较⼩的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化⼩的过程。
坏处:
int Fib ( int n){if (n<= 2 )return 1 ;elsereturn Fib(n -1 )+Fib(n -2 );}# include <stdio.h>int main (){int n = 0 ;scanf ( "%d" , &n);int ret = Fib(n);printf ( "%d\n" , ret);return 0 ;}
但是当我们n输⼊为50的时候,需要花费多久时间才能算出结果呢?这时计算所花费的时间,是我们能难接受的吗?其实递归程序会不断的展开,在展开的过程中,我们很容易就能发现,在递归的过程中会有重复计 算,⽽且递归层次越深,冗余计算就会越多。
# include <stdio.h>int count = 0 ;int Fib ( int n){if (n == 3 )count++; // 统计第 3 个斐波那契数被计算的次数if (n<= 2 )return 1 ;elsereturn Fib(n -1 )+Fib(n -2 );}int main (){int n = 0 ;scanf ( "%d" , &n);int ret = Fib(n);printf ( "%d\n" , ret);printf ( "\ncount = %d\n" , count);return 0 ;}
在计算第40个斐波那契数的时候,使⽤递归⽅式,第3个斐波那契数就被重复计算了39088169次,这些计算是⾮常冗余的。所以斐波那契数的计算,使⽤递归是⾮常不明智的,我们就得想迭代的⽅式解决。
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;} 迭代的⽅式去实现这个代码,效率就要⾼出很多了
本篇文章就到此结束,希望有所能帮到 读者更好的了解函数递归与迭代。