递归与栈
递归是一个重要的概念,同时也是一种重的程序设计方法。简单地说,如果在一个函数、过程或数据结构的定义中又应用了它自身(作为定义项之一),那么这个函数、过程或数据结构称为是递归的定义的,简称递归。例如,阶乘函数可递归定义如下:
必须注意,递归定义不能是"循环定义"。为此要求任可递归定义必须同时满足如下两个条件:
①被定义项在定义中的应用(即作为定义项的出现)具有更小的"尺度";
②被定义项在最小"尺度"上的定义不是递归的。
例如,在上述阶乘函数的定义中,被定义项n!在定义中的应用(n-1)!具有比原来(即n)更小的"尺度"(即n-1)。同时,n!在最小"尺度"(即0)上的定义不是递归的(由自然数1直接定义)。这两个条件实际上构成了递归程序设计的基本原则。此外,通常将反映条件②的部分写在递归过程的开头。
很多实际递归定义的。对于这些问题很容易写出求解它们的递归算法。计算阶乘函数的递归算法如下:
递归过程的运行引起递归调用。例如,f(3)的执行中出现的递归调用——返回过程如图3-5(a)所示。
f3 | | f2 | | f1 | | f0 →┐ │ │ |
r1┌ | ←┐ | t1┌ | ←┐ | t1┌ | ←┐┈┈ | │ ↓ ┈┘1 |
图3-5(a) f(3)执行递归调用─返回次序
|
|
|
|
|
|
|
|
|
|
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||
top→ | 调用f2前 | 调用f2后 | 调用f1后 | 调用f0后 | 返回f1后 | 返回f2后 | top→ | 返回 f3后 |
图3-5(b) 相应的工作栈状态变化
递归调用——返回的控制与非递归过程的控制并无本质区别,同样可由一个工作栈实现。对上述过程f,返回位置r应设在内、外层return语句这间。为了区别返回到哪一级递归,可在返回位置进栈的同时将该次调用的参数一起保存。图3-5(b)所示为与(a)相应的工作栈状态变化过程。
原文地址:http://www.nhyz.org/nhxi/nhxi/jiegousuanfa/jiegou22.htm