本质上,尾递归函数会不断调用自身,直到达到其结束条件。然而,与“常规”递归不同,它会将中间答案传递给自身,直到到达终点。
一个例子是这样的:
(define (find-length i lst)
(if
(null? lst) i
(find-length (+ i 1) (cdr lst))))
该函数有两个值:i
,它跟踪到目前为止列表的长度,以及lst
我们正在计算元素的列表。i
,出于所有意图和目的,是我们对列表中元素的运行计数。所以如果我们调用这个方法,我们会希望调用它时i
初始化为 0。
首先我们检查列表是否为空。( null?
) 如果列表为空,我们可以假设我们已经计算了所有元素,所以我们只需返回i
,这是我们的运行计数。这是我们的最终条件。
否则,我们find-length
再次调用。然而,这一次,我们增加i
了 1 并从 list 中删除了第一个元素(cdr lst)
。
例如,假设我们这样调用函数:
(find-length 0 (list 2 3 4 3 5 3))
正如我们评估的那样,该程序将递归调用:
(find-length 1 '(3 4 3 5 3))
(find-length 2 '(4 3 5 3))
(find-length 3 '(3 5 3))
(find-length 4 '(5 3))
(find-length 5 '(3))
(find-length 6 '()) ; end condition, return 6
这个问题通常是尾递归的一个很好的参考。