C语言之递归
1.递归是什么
- 认识递归
递归作为一种算法在程序设计语言中广泛应用. - 递归的定义
递归是指程序调用自身的过程,在数学和计算机科学中,递归指由一种或多种简单的基本情况定义的一类对象或方法,并规定其他所有情况都能被还原为基本情况.
2.递归的条件
- 子问题需要和原来的问题做相同的事,并且更加简单.
- 不能无限制的调用本身,必须要能够结束.
3.递归的用途
- 数据的定义是按照递归进行定义的.
- 问题解决的办法是按照递归的算法实现.
- 数据的结构形式是递归定义的.
4.递归的要素
- 递归的结束条件
不管是在递归算法,还是在递归的函数调用过程中,递归都需要有一个结束条件,也就是递归出口。通常,在递归的结束时,我们能够直接知道递归的结果。 - 递归的等价关系式
用数学表达式来进行表示,常见的离散形式是:
f(x)=n+f(x-1)
其中,n是一个常量,x-1最终会收敛成一个常量,然后结束递归。在递归算法和递归函数中,递归表达式是程序调用递归的方式。 - 递归传递的参数
在递归算法中,如上式所示,x就是递归需要传递的参数。在递归函数中,我们通常将递归封装成一种函数,通过递归的关系式,将函数进行返回和调用,用来实现递归的过程。
5.递归的流程图
如图所示,是一个递归的过程,由初始状态,通过不断递归,达到状态X,最后进入结束状态,这就是一个递归的过程。
6.递归的实战
def fact_resursion(n):
# 终止条件
if n==1:
return 1 #递归结束条件
else:
return n*fact_resursion(n-1) # 循环部分
print(fact_resursion(5))
- 上述过程是一个通过递归实现N的阶乘的函数,函数的结束条件是当N=1时。N!表示N*(N-1)* …* (1)的一个过程,不难发现在N的变化中,N一直实现N=N-1的操作,由此可以推导出递归的循环。
def fun(n):
# 终止条件
if n <=1:
return n
else:
return fun(n-1) + fun(n-2) # 循环部分
print(fun(8))
- 斐波那契数列 ,就是一个非常典型的递归调用过程。其具体数列为 0 1 1 2 3 5 8 13.通过归纳总结可以得出f(0)=0,f(1)=1,f(n)=f(n-2)+f(n-1),n>0这个规律.通过这个规律,我们可以利用递归的方式进行实现.
7.递归与循环
相同点:
- 递归和循环的本质都是代码的复用。
- 递归和循环在理论上具有相同的计算能力(在可计算理论中,这两种计算模型所计算的函数类是相同的).
- 递归可以看做是一种特殊的循环.
不同点: - 递归需要通过程序和系统一起完成,而循环可以由程序单独完成。
- 递归的规模很小,受到系统工作栈大小的限制,而循环的规模很大,机会不会受到影响.
- 递归的代码更加简单,容易理解,可读性强,但是,递归占用的内存空间比函数大,受到限制.
8.递归,循环,迭代
- 从概念上讲,递归就是指程序调用自身的编程思想,即一个函数调用本身;迭代是利用已知的变量值,根据递推公式不断演进得到变量新值得编程思想。简单地说,递归是重复调用函数自身实现循环。迭代是函数内某段代码实现循环.
- 而迭代与普通循环的区别是:循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值.
- 迭代与普通循环的区别是:迭代时,循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值.
递归与普通循环的区别是:循环是有去无回,而递归则是有去有回(因为存在终止条件).
在循环的次数较大的时候,迭代的效率明显高于递归.
递归
int fib(int n){
if(n>1) return fib(n-1) + fib(n-2);
else return n; // n = 0, 1时给出recursion终止条件
}
迭代
int fib(int n){
int i, temp0, temp1, temp2;
if(n<=1) return n;
temp1 = 0;
temp2 = 1;
for(i = 2; i <= n; i++){
temp0 = temp1 + temp2;
temp2 = temp1;
temp1 = temp0;
}
return temp0;
}
9总结
递归是一种特殊的循环,通过调用自身.在使用过程中,通常将递归封装成一种函数进行使用.同时,递归需要考虑内存空间的分配.因此,在实际使用过程中,我们需要考虑递归的复杂度,递归的表达式以及递归的结束条件.