最近在学习算法,却发现自己对迭代和递归傻傻分不清,脑子转不过来弯儿,所以自己又学习了一下。
如果你和我一样分不清迭代和递归,那我衷心希望这篇文章能够帮助到你。
本篇只是通过一个简单的例子来说明迭代和递归,对于二者在算法中更深层次的运用不加以说明。
如有错误,欢迎指正,我会及时更正错误。
迭代(iteration):the process of repeating a mathematical or computing process or set of instructions again and again, each time applying it to the result of the previous stage
递归(recursion):the process of repeating a function, each time applying it to the result of the previous stage
(摘自牛津字典英文释义,都很简单,就不翻译了)
我们可以看出,迭代和递归都是在重复。
但是它们重复的内容,重复的方式不一样。
看一个最熟悉不过的例子吧——配波拉契数列:1,1,2,3,5,8,…得到f(n)
分析:
递归法:
int f(int n){
if(n==1||n==2){
return 1;
}
else{
return f(n-1)+f(n-2); //递归调用表达式
}
}
递归,我们看名字就知道,它是分为两个过程:递推和回归
比如,我要计算f(6)
黄色箭头表示递推的过程,蓝色箭头表示回归的过程
由此可见,递归就是将一个规模为n的问题将其一级一级地向下分解,最终我们可以分解到 n0 或 n1 或 n== 2 时的初始值,得到初始值后,我们再一级一级地回归,得到最终结果。
所以递归解决的问题是这个样子的:
要解决一个规模为n的问题,能够设法将其分解成规模较小的问题,而这些小问题能够很方便地构造出大问题的解,并且这些小问题也能采用同样的分解和综合的方法,分解成为规模更小的问题。最后规模小到可以直接得解。
递归特点:
函数要直接或间接调用自身
要有递归终止条件检查,我每一次进行递归调用都是要越来越靠近这个终止条件的
如果不满足递归终止条件,则调用涉及递归调用的表达式。
问题:
由上面求f(6)的过程我们就可以发现,我们进行了好多重复的运算,如计算f(4)的过程,我们进行了两次。所以递归算法的执行效率相对较低。
迭代法:
int f(int n){
int f1=1,f2=1; //确定迭代变量
int t=0;
if(n==1||n==2){
return 1;
}
else{
for(int i=3;i<=n;i++){ //对迭代过程进行控制
t=f1+f2;
f1=f2;
f2=t; //建立迭代关系式
}
return t;
}
}
同样地,我们还是来计算f(6)
我们先设置了迭代变量f1,f2,t
之后在每一轮循环中都通过我们建立的迭代关系式不断更新迭代变量
最后的t值就是我们要的结果
迭代特点:
通过我们建立的关系式不断地去更新我们设的迭代变量
通俗地讲,迭代是在不断前进的,没有回头
迭代的准备工作:
- 确定迭代变量
在那些可以用迭代算法解决的问题中,应至少存在1个直接或间接不断由旧值递推出新值的变量
- 建立迭代关系式
即如何从前一个变量的值推出下一个值的公式
- 对迭代过程进行控制
即为整个过程设置一个结束点
总结:
递归就是不断将问题划分为规模小的子问题,直到能够直接得解,然后再一级一级向上回归,综合小规模问题的解,最终得到原始问题的解。
迭代是通过建立的关系式,不断地由旧值得到新值,始终是在前进的。