递归与栈的关系

 

递归与栈
  递归是一个重要的概念,同时也是一种重的程序设计方法。简单地说,如果在一个函数、过程或数据结构的定义中又应用了它自身(作为定义项之一),那么这个函数、过程或数据结构称为是递归的定义的,简称递归。例如,阶乘函数可递归定义如下:
  必须注意,递归定义不能是"循环定义"。为此要求任可递归定义必须同时满足如下两个条件:
  ①被定义项在定义中的应用(即作为定义项的出现)具有更小的"尺度";
  ②被定义项在最小"尺度"上的定义不是递归的。
  例如,在上述阶乘函数的定义中,被定义项n!在定义中的应用(n-1)!具有比原来(即n)更小的"尺度"(即n-1)。同时,n!在最小"尺度"(即0)上的定义不是递归的(由自然数1直接定义)。这两个条件实际上构成了递归程序设计的基本原则。此外,通常将反映条件②的部分写在递归过程的开头。
  很多实际递归定义的。对于这些问题很容易写出求解它们的递归算法。计算阶乘函数的递归算法如下:
  public static int nn(int i) { if (i == 0) { return 1; } else return i * nn(i - 1); }
  递归过程的运行引起递归调用。例如,f(3)的执行中出现的递归调用——返回过程如图3-5(a)所示。

 f3
 │
 ↓
r└

    
  
 ┌┈┘
┈┘

 f2
→┐
 ↓
t└

    
  ┌ 
 ┌┈┘ 
┈┘

 f1
→┐
 ↓
 t└

    
  ┌ 
 ┌┈┘ 
┈┘

 f0
→┐
 │
 │

r1┌
 │
 ↓

←┐ 
 └┈┐ 
6 

t1┌
 ↓
┈┘

←┐ 
 └┈┐ 
2 

t1┌
 ↓
┈┘

←┐┈┈
 └┈┐ 
1  

 │
 ↓
┈┘1

 图3-5(a) f(3)执行递归调用─返回次序

 

 
 
 
 




top

 
 
 
3 r



top

 
 
2 r
3 r


top

 
1 r
2 r

3

r



top

 
 
2 r
3 r




top

 
 
 
3 r



 
 
 
 

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

欢迎:

 

你可能感兴趣的:(数据结构,工作,算法)