将递归算法改为非递归算法
1.递归与非递归的区别:
递归的代码量比非递归的代码量少,因为非递归需要额外的变量记录当前所处的位置信息,以及额外的控制语句。而递归所使用的方式是函数调用,这是非常自然的栈结构,不需要记录位置信息,不需要添加控制语句,这些工作都由函数调用的特性解决了。
递归的执行效率比非递归的执行效率低,因为递归的实质是函数调用,而函数调用必然要进行线程栈空间的分配,记录每一次函数调用前的状态等工作,开销是比较大的。而非递归则不需要进行这些工作。
递归与非递归调用最主要区别就是在函数调用上。在计算机的工作方式中,函数调用是以栈结构来实现的,最早调用的函数处于栈底,最晚调用的函数处于栈顶,栈中存放的是每个函数中的局部变量等信息,当函数调用返回时该函数相关的信息就会从栈中弹出。
由此可以看出,递归每深入一层,栈的深度也会加一,而且当每一层的递归调用结束,都会自动返回上一层的递归中,因此不需要额外的变量记录当前所处的递归位置,也不需要while、if等控制语句进入或返回上一层或下一层递归。因此代码量比非递归的少。
但正因为函数调用要在栈中进行各种操作,例如分配新的空间,保存当前函数调用的信息,为新的函数调用初始化等,效率比较低下。所以递归的效率比非递归的低。
2.转化
递归是指某个函数或过程直接或间接的调用自身。一般地一个递归包括递归出口和递归体两部分,递归出口确定递归到何时结束,而递归体确定递归求解时的递推关系。递归算法有两个基本特征:一是递归算法是一种分而治之的、把复杂问题分解为简单问题的求解问题方法,对于求解某些复杂问题,递归算法分析问题的方法是有效地;而是递归算法的时间、控件效率通常比较差。因此对解决某些问题时,我们希望用递归算法分析问题,用非递归算法解决问题,这就需要把递归算法转换为非递归算法。
把递归算法转化为非递归算法有如下三种基本方法:
(1). 通过分析,跳过分解过程,直接用循环结构的算法实现求解过程。
(2). 自己用栈模拟系统的运行时栈,通过分析只保存必须保存的信息,从而用非递归算法替代递归算法。
(3). 利用栈保存参数,由于栈的后进先出特性吻合递归算法的执行过程,因而可以用非递归算法替代递归算法。
3.分析
递归深度小于3的,优化结果不明显。大于3的,优化后差距能达到70%以上。
目前QQ超市1店5口,以后2店3口之后的图,递归深度甚至达到了60层。
经过测试发现路径算出速度低了10多倍。非递归的转换势在必行!!
要回去从头学一下二叉树了……