递归算法

更新时间:2024-01-12 11:13

递归算法(recursive algorithm、recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。

简介

递归算法应用的场景是要解决的问题和其子问题具有相似性的时候,通过直接或间接的调用自己求出问题解的方法。它是通过解决一个问题的更小实例来解决一个大的问题的解的算法。递归算法有两个过程,一是调用过程,二是向上传递结果的过程。

递归程序

在支持自调用的编程语言中,递归可以通过简单的函数调用来完成,如计算阶乘的程序在数学上可以定义为:

这一程序在Scheme语言中可以写作:

不动点组合子

即使一个编程语言不支持自调用,如果在这语言中函数是第一类对象(即可以在运行期创建并作为变量处理),递归可以通过不动点组合子(英语:Fixed-point combinator)来产生。以下Scheme程序没有用到自调用,但是利用了一个叫做Z 算子(英语:Z combinator)的不动点组合子,因此同样能达到递归的目的。

这一程序思路是,既然在这里函数不能调用其自身,可以用 Z 组合子应用(application)这个函数后得到的函数再应用需计算的参数。

尾部递归

尾部递归是指递归函数在调用自身后直接传回其值,而不对其再加运算。尾部递归与循环是等价的,而且在一些语言(如Scheme中)可以被优化为循环指令。 因此,在这些语言中尾部递归不会占用调用堆栈空间。以下Scheme程序同样计算一个数字的阶乘,但是使用尾部递归

能够解决的问题

递归数据

数据类型可以通过递归来进行定义,比如一个简单的递归定义为自然数的定义:“一个自然数或等于0,或等于另一个自然数加上1”。Haskell中可以定义链表为:

这一定义相当于宣告“一个链表或是空串列,或是一个链表之前加上一个字符串”。可以看出所有链表都可以通过这一递归定义来达到。

免责声明
隐私政策
用户协议
目录 22
0{{catalogNumber[index]}}. {{item.title}}
{{item.title}}