首先,我们先了解下递归。说到递归,数据结构中树介绍章节中有大量的实例用了,包括二叉树定义与遍历等。当然一般公司项目中很少用它,主要是效率低下,同时递归涉及到函数反复建栈,压栈,销毁栈的过程,开销较大。这里仅仅作为一种技术探讨来研究。递归,简单地说就是函数自己调用自己,网上也有不少解释了。这里我的看法是将整个递归过程看做一种函数映射关系,即 F(A) --> B,如果B与A具有相同的属性和操作,同时B的作用域小于A的作用域,算法逐步收敛的话,就可以用递归来描述了。之前看过SCIP《计算机程序构造与解释》一书,里面讲到了函数式编程语言scheme,该书中将函数作为头等公民,所有操作都用函数来体现,用了大量的递归实现,状态值也是保存在函数入参中(这里也称作尾递归)。书中将函数看做某种规则,数据作为函数的输入,可以抽象理解为函数为对数据进行的操作行为,函数参数为输入数据;如果我们用更底层地用汇编方式描述就是函数可以看做代码段(对一类算法行为的描述),数据看做数据段(是对现有数据的集合)。那么程序本质上就是一段用可计算公式描述的抽象过程,简单地说就是一组相同属性集合上面的相同映射关系。比如说整数域上的加法运算,其动作为加法,数据就是整个整数集合。每个整数对于加法这个“规则”来说都是等价的,用scheme语言很容易描述这一点:(+ a b)。将算法与数据区别对待的好处就是很容易识别出规则。如果是数值计算的话,则便于用递归来描述。总之,递归适用于有明显递归特性的数据结构(比如树),或者有着明显递归公式,可以用数学归纳法证明的问题。我们来看一位大牛给出的通用递归公式:
Result M(Problem prob)
{
if (<problem can be solved easily>) //递归入口条件,不然就是无限递归了
return <easy solution>;
// The problem cannot be solved easily. //其他条件,满足相同的处理方式就可以了