转自:人机与认知实验室
如涉版权请加编辑微信iwish89联系
哲学园鸣谢
许多时候,人们对事物常常不能获得绝对信号(态)的感知,那么就尝试选择能否获得变化信号(势)的意识,这些变化既包括递归也涉及迭代。那么两者究竟有何区别呢?
先讲个故事吧。
从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”。
这个故事永远也讲不完,因为没有递归结束条件。老师讲递归时总是说,递归很简单,一个递归结束条件,一个自己调用自己。如果递归没有结束条件,那么就会无限递归下去。在编程的时候,没有递归结束条件或者递归过深,一般会造成栈溢出。
递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。(Fibonacci函数)
(2)问题解法按递归算法实现。(回溯)
(3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)
迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。
为什么使用迭代而不用递归呢?
很明显,使用递归时每调用一次,就需要在栈上开辟一块空间,而使用迭代就不需要了,因此,很多时候设计出了递归算法,还要想法设法修改成迭代算法。
假如现在我们不考虑编程,我们仅仅看一下上面使用递归和迭代求1 2 3… n的过程。
使用递归:
sum(5)
5 sum(4)
5 4 sum(3)
5 4 3 sum(2)
5 4 3 2 sum(1)
5 4 3 2 1 sum(0)
5 4 3 2 1 0
5 4 3 2 1
5 4 3 3
5 4 6
5 10
15
使用迭代
0 1=1
1 2=3
3 3=6
6 4=10
10 5=15
上面两个计算过程所需的步骤都是O(n)。但是两个计算过程的形状不一样。
递归过程是一个先逐步展开而后收缩的形状,在展开阶段,这一计算过程构造起一个推迟进行的操作所形成的的链条(这里是 ),在收缩阶段才会实际执行这些操作。这种类型的计算过程由一个推迟执行的运算链条刻画,称为一个递归计算过程。要执行这种计算过程,就需要维护以后将要执行的操作的轨迹。在计算1 2 3 … n时,推迟执行的加法链条的长度就是为了保存其轨迹需要保存的信息量,这个长度随着n值而线性增长,这样的过程称为线性递归过程。
迭代过程的形成没有任何增长或收缩。对于任意一个n,在计算的每一步,我们需要保存的就只有i,ret,这个过程就是一个迭代计算过程。一般来说,迭代计算过程就是那种其状态可以用固定数目的状态变量描述的结算过程。在计算1 2 … n时,所需的计算步骤与n成正比,这种过程称为线性迭代过程。
程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。
递归与迭代都是基于控制结构:迭代用重复结构,而递归用选择结构。
举个例子吧:你要给某个小孩子买玩具。
递归:你自己不太了解小孩子的需求,为了缩小范围,让你的儿子去给孙子挑选。儿子比你强点有限,但依然不太了解小孩子的需求。为了缩小范围,你又让你孙子去挑选。如此这般,直到找到合适的玩具。
迭代:你挑了一件觉得不行,又挑了一件又不行。如此这般,直到找到合适的玩具。
所以一句话:递归是自己调用自己,每次旨在缩小问题规模。迭代是自己执行很多次,每次旨在更接近目标。
迭代是逐渐逼近,用新值覆盖旧值,直到满足条件后结束,不保存中间值,空间利用率高。
递归是将一个问题分解为若干相对小一点的问题,遇到递归出口再原路返回,因此必须保存相关的中间值,这些中间值压入栈保存,问题规模较大时会占用大量内存。
相关链接
你读过数学书,但你修炼过数林秘籍吗?