在我上一个博客上,素数计算机的试验目标里里面涉及到了递归的使用。但个人始终对于递归只是硬记而已 ,并不理解递归是啥。
那么先讲一下递归是
递归是什么
递归是一种编程技巧,它允许一个函数在执行过程中调用它自己。这种调用自身的操作可以帮助我们以简洁和清晰的方式解决那些可以分解为更小相似问题的问题。在数学和计算机科学中,递归函数的定义通常包含对自身的引用。
从理论上讲,递归可以通过不断地将问题细分为更小的子问题,一直分解到最简单的情况,然后从这个最简单的情况开始逐步构建出整个问题的解。在递归调用中,有两个重要的步骤:
递(分解):函数调用自身以处理较大问题的较小部分。
归(回归):在解决了最简单的问题后,递归调用开始返回,逐步构建出原始问题的解。
然而,递归可能会导致栈溢出的问题,因为每一次函数调用都需要在栈上分配新的内存空间。如果递归深度过大,会耗尽系统栈空间。尾递归是递归的一种特殊形式,它发生在递归调用是函数体中的最后一个操作,并且没有任何计算与该递归调用一起执行。这种形式的递归可以被某些编译器或解释器优化,使得无论递归调用多少次,都只占用一个栈帧,从而避免了栈溢出的问题。
一个简单的递归阶乘函数可以表示为:
f ( n ) = { 1 if n = 0 n × f ( n − 1 ) if n > 0 f(n) = \begin{cases} 1 & \text{if } n = 0 \\ n \times f(n-1) & \text{if } n > 0 \end{cases} f(n)={1n×f(n−1)if n=0if n>0
这个定义展示了递归的基本形式:函数
在定义中调用了自身。尾递归优化的一个例子可以用以下表示:
int factor (int n)
{
if (n =0) return 1;
else return n*factor(n-1};
}
ps:(顺带提一嘴)尾递归递归优化的关键在于,递归调用是函数返回的最后一个操作,没有额外的计算与它结合。这使得编译器或解释器可以将递归优化为循环,从而减少栈空间的使用。可以使用for循环来解决 ,如下
int factor(int n)
{
int result=1;
for(int i,i<=n,i++)
{
result=result*n;
}
}
```
## 递归的图示
