最近在写二叉树遍历时,察觉到了递归和迭代,感觉有必要了解一下,在看了几遍有关递归(recursion)和迭代(iteration)的文章后,觉得很不错,本着分享学习的态度想直接转发过来以便记录,但是我觉得还不如自己写一遍有益于深刻记忆 原文两遍地址:https://blog.csdn.net/laoyang360/article/details/7855860,https://blog.csdn.net/LG1259156776/article/details/46849809
递归:
一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。
1:它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
2:递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
3:在使用递归时,必须有一个明确的递归结束条件,称为递归出口.
4:递归分为两个阶段:递推和回归
递推:把复杂的问题的求解推到比原问题简单一些的问题的求解;
回归:当获得最简单的情况后,逐步返回,依次得到复杂的解.
迭代:
对计算机特定程序中需要反复执行的子程序*(一组指令),进行一次重复,即重复执行程序中的循环,直到满足某条件为止,
是利用已知的变量值,根据递推公式不断演进得到变量新值得编程思想。
1:其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。
递归和迭代比较:
递归是应用程序自身调用自身,以实现层次数据结构的查询和访问。递归的使用可以使代码更简洁清晰,可读性更好(对于初学者到不见得),如果递归深度太大,可能系统资源会不够用。递归需要系统堆栈,所以空间消耗要比非递归代码要大很多,容易出现栈溢出问题。往往有这样的观点:能不用递归就不用递归,递归都可以用迭代来代替。
在理论上,递归和迭代在时间复杂度方面是等价的(在不考虑函数调用开销和函数调用产生的堆栈开销),但实际上递归确实效率比迭代低。
所有的递归函数都可以转换为迭代函数,反之亦然,然而代价通常都是比较高的。但从算法结构来说,递归声明的结构并不总能够转换为迭代结构,原因在于结构的引申本身属于递归的概念,用迭代的方法在设计初期根本无法实现,这就像动多态的东西并不总是可以用静多态的方法实现一样。
这也是为什么在结构设计时,通常采用递归的方式而不是采用迭代的方式的原因,一个极典型的例子类似于链表,使用递归定义及其简单,但对于内存定义(数组方式)其定义及调用处理说明就变得很晦涩,尤其是在遇到环链、图、网格等问题时,使用迭代方式从描述到实现上都变得不现实。因而可以从实际上说,所有的迭代可以转换为递归,但递归不一定可以转换为迭代。
采用递归算法需要的前提条件是,当且仅当一个存在预期的收敛时,才可采用递归算法,否则,就不能使用递归算法。
递归编程所体现的思想正是人们追求简洁、将问题交给计算机,以及将大问题分解为相同小问题从而解决大问题的动机。方便了程序员难为了机器,递归可以通过数学公式很方便的转换为程序。
其优点就是易理解,容易编程。但递归是用栈机制实现的,每深入一层,都要占去一块栈数据区域,对嵌套层数深的一些算法,递归会力不从心,空间上会以内存崩溃而告终,而且递归也带来了大量的函数调用,这也有许多额外的时间开销。所以在深度大时,它的时空性就不好了。
而迭代效率高,运行时间只因循环次数增加而增加,没什么额外开销,空间上也没有什么增加,但缺点就是不容易理解,编写复杂问题时困难。
总结:
递归:程序调用自身
优点:
- 大问题变为小问题,可以极大的减少代码量;
- 符合人基本思维方式,好理解
- 代码更简洁清晰,可读性更好
缺点:
- 递归调用函数,浪费空间;
- 递归太深容易造成堆栈的溢出;
迭代:利用已知的变量值,根据递推公式不断演进得到变量新值
优点:
- 迭代效率高,运行时间只因循环次数增加而增加;
- 没什么额外开销,空间上也没有什么增加;
缺点:
- 不容易理解;
- 代码不简洁;
- 编写复杂问题时困难;