一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。(Fibonacci函数)
(2)问题解法按递归算法实现。(回溯)
(3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)
递归的执行过程可分为分解和求值两部分。首先是逐步把“大问题”分解成形式相同但规模很小的“小问题”,直至分解到递归出口。一旦遇到递归出口,分解过程结束,开始求值过程,所以分解过程是“量变”过程,即原来的“大问题”在慢慢变小,但尚未解决。遇到递归出口后,便发生了“质变”,即原递归问题转换成直接可以求值的简单问题。递归只需要少量的步骤就可描述解题过程中所需要的多次重复计算,极大地减少了代码量。该算法设计的关键在于,找出递归方程和边界条件(递归出口)。递归关系就是使问题向边界条件转化的过程,所以递归关系必须能使问题越来越简单,规模越小。没有设定边界的递归是死循环。
递归算法设计通常需要按照以下3个步骤:
(1)分析问题,得出递归关系;
(2)设置边界条件,控制递归;
(3)设计函数,确定参数。
递归算法具有以下三个基本规则:
(1)基本情形:至少有一种无需递归即可获得解决的情形,也即前面说的边界条件。
(2)进展:任意递归调用必须向基本情形迈进,即前面所说的使得问题规模变小。
(3)正确性假设:总是假设递归调用是有效的。
递归调用的有效性是可以用数学归纳法证明的,所以当我们在设计递归函数时,不必设法跟踪可能很长的递归调用途径(比如Hanoi Tower问题)。这种任务可能很麻烦,易于使设计和验证变得更加困难。所以我们一旦决定使用递归算法,则必须假设递归调用是有效的。
与递归相对应的递推算法是一种用若干步可重复的简单运算(规律)来描述复杂问题的方法。
递推算法以初始(起点)值为基础,用相同的运算规律,逐次重复运算,直至运算结束。这种从“起点”重复相同的方法直至到达一定“边界”,犹如单向运动,用循环可以实现。递推的本质是按规律逐次推出(计算)先一步的结果。
在算法设计时,能用递推实现的算法一般都可以用递归来实现。能用递归实现的算法不一定能够通过递推实现。就算法的效率而言,递推优于递归