1. 递归是什么?
先来看最简单的递归代码:
#include <stdio.h>
int main()
{
printf("Hello World\n");
main();
return 0;
}
在main函数里还有一个main函数,在XXX函数里有XXX函数,这种就是递归
在函数里调用自己,但这种情况会无限打印Hello World,最后导致栈溢出
递归的递就是递推的意思,归就是回归的意思,上面的代码则是一直在递,没有归,所以导致栈溢出,所以一定要设置好结束条件,具体怎么做往下看看
2. 怎么正确使用递归?
经典的一题就是使用递归完成n的阶乘
2.1 递归求n的阶乘
我们知道n的阶乘是n*(n-1)*(n-2)...*2*1
所以我们要不断使用这个Fact函数直至它递归到1,所以需要Fact(n-1)
#include <stdio.h>
int Fact(int n)
{
if (n == 1)
return 1;
return n * Fact(n - 1);
}
int main()
{
int n;
scanf("%d", &n);
int ret = Fact(n);
printf("%d", ret);
return 0;
}
可以这么理解,最后return的东西里n就是你需要的结果的过程,而后面的Fact(n-1)就是为了后续
前面的 if 语句就是一个结束条件,如果没有这个条件会和上面的代码一样栈溢出,导致程序崩溃
我们设置了 n-1 后 n只要不是小于1的数终有结束的那次
画图推演:
3. 为什么要使用递归?
其实我们求阶乘使用循环也是可以做出来的
#include <stdio.h>
int Fact(int n)
{
int ret = 1;
for (int i = 1; i <= n; i++)
{
ret *= i;
}
return ret;
}
int main()
{
int n;
scanf("%d", &n);
int ret = Fact(n);
printf("%d", ret);
return 0;
}
这个代码所需要消耗的时间比递归更短,且不需要占用更多空间
所以在求阶乘时使用循环明显更好
但是我们还是要学习递归,因为并不是所有问题都是循环能够解决的,有时候递归能够更加直观简单
总结
在解决某些问题时,如果这个问题递归和循环两者皆可,那么建议使用循环
理由:
1.循环时间复杂度低
2.循环空间复杂度低
3.代码简单易懂
但是在某些比较棘手的困难问题上,循环会很麻烦,而且不容易想出来,这个时候可以尝试使用一下递归
理由:
1.递归实现较容易
2.递归可简化问题
学习递归是有助于我们后期学习数据结构的,在学习树的时候会大量使用递归,所以递归是一个重要的内容
感谢观看
--------------------------------------------------------------------------------------------------------
完