算法-递归思想

来源:互联网 发布:mac dmg 安装 编辑:程序博客网 时间:2024/05/17 02:57

递归

如果想使用递归算法解决问题:
那么此问题必须满足 f(X)=nf(x); 能把f(X)转化为f(x) - 转化为若干个相同的子问题

解决思路:

1.找出递归公式
2.找出递归终止条件

问:求n的阶乘
分析:
n的阶乘为 n*(n-1)*(n-2)…*1
也就是:nf(x)—— 若干个子问题
终止条件 :*1

//时间复杂度O(n)function recursion(n){if(n==0){//终止条件    return 1;}else{return n*recursion(n-1);}}console.log(recursion(5));

循环方式实现:

function itordinary(n){var iNums=1;for(var i=1;i<n;i++){ iNums=iNums*(i+1);}return iNums;}console.log(itordinary(5));

总结:

递归算法:

优点:代码简洁、清晰,并且容易验证正确性。

缺点:它的运行需要较多次数的函数调用,如果调用层数比较深,每次都要创建新的变量,需要增加额外的堆栈处理,会对执行效率有一定影响,占用过多的内存资源。

循环算法:

优点:速度快,结构简单。

缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。

大神分析:

(1)递归都可以改成循环。这个命题如何评价?(厉害了 word哥)

我先说下结论,就是,这个命题是成立的,但是,如果只看到这个结论,对问题的认识则是片面的,不完整的。

也就是说,只看到了递归和循环的共同点:都是 EIP 在同一段代码段内反复。

而没有注意到两者在模型,重复代码段之间的层次结构,和流程控制方面的差异。

但是,它忽略了另一个层面,就是递归和循环的思维模型上的差异性。
我先打个比喻,递归是自相似的,就好比分形图,两次重复代码段之间,是有结构,层次上的“父子”关系的。

我用鼠标手绘了一个草图,不是那么完美,感受一下就好(下图是主观感受示意,可能不太严谨的):
这里写图片描述

而循环呢,思维模型里,它是每层循环是在一个维度上的。

递归在重复的代码片段内,每一层,都有自己独立的一套上下文。在堆叠。
循环,是在同一个层次之内的。

所以,由于这种模型上并不是完全匹配,所以虽然可以相互转换,但是实际上算法内部是有一定的“重新加工”的过程。

终极总结:

递归思维模型: 是有多层维度的,每一层,都有自己独立的一套上下文。在堆叠。,两次重复代码段之间,具有结构,层次上的“父子”关系的。(这个就是递归思想 oh my god)

循环思维模型: 只是在一个维度上,公用一套上下文,两次重复代码段之间,具有结构,层次上的”兄弟”关系的

0 0