首页 > 代码库 > 递归转非递归(13条消除规则)

递归转非递归(13条消除规则)

直接递归的消去规则:
 基本思路:将递归调用的地方用等价的非递归代码来代替,并对return语句做适当处理。
13条规则:处理直接递归调用和return语句,将之转换成等价的迭代代码。

初始化  
   ⑴ 在过程的开始部分,插入说明为栈的代码并将其初始化为空:  StackType Stack[1..SIZE]
      Top ← 0
    在一般情况下,这个栈用来存放参数、局部变量和函数的值、每次递归调用的返回地址。
   ⑵ 将标号L1附于第一条可执行语句。
      ...  
   L1:第一条可执行语句
      ...
 然后对于每一处递归调用都用一组执行下列规则的指令来代替。
 处理递归调用语句
  ⑶ 将所有参数和局部变量的值存入栈。
     Top ← Top +1
     Stack[Top] ← …
     栈顶指针可作为一个全程变量来看待。
  ⑷ 建立第i个新标号Li,并将标号的下标i存入栈。这个标号的i值将用来计算返回地址。
     Top ← Top +1
     Stack[Top] ← i
     此标号放在规则⑺所描述的程序段中。
  ⑸ 计算这次调用的各实在参数(可能是表达式)的值,并把这些值赋给相应的形式参数。

  ⑹ 插入一条无条件转向语句转向过程的开始部分:
      goto L1

  (以上完成一次递归调用)
对退出点的处理
  ⑺ 如果这过程是函数,则对递归过程中含有此次函数调用的那条语句做如下处理:将该语句的此次函数调用部分用从栈顶
取回该函数值的代码来代替,其余部分的代码按原描述方式照抄,并将⑷中建立的标号附于这条语句上。


   如果此过程不是函数,则将⑷中建立的标号附于⑹所产生的转移语句后面的那条语句。

以上步骤消去过程中的递归调用。

下面对过程中出现return语句进行处理。
  注:纯过程结束处的end可看成是一条没有值与之联系的return语句
对每个有return语句的地方,执行下述规则:
 
  ⑻ 如果栈为空,则执行正常返回。
     if top = 0 then return(…)
 
  ⑼ 否则,将所有输出参数(带有返回值的出口参数,out/ inout型)的当前值赋给栈顶上的那些对应的变量。
     
     Stack[n] ← …
  ⑽ 如果栈中有返回地址标号的下标,就插入一条此下标从栈中退出的代码,并把这个下标赋给一个未使用的变量。
     addr ← Stack[Top]
     Top ← Top -1
  ⑾ 从栈中退出所有局部变量和参数的值并把它们赋给对应的变量。

  ⑿ 如果这个过程是函数,则插入以下指令,这些指令用来计算紧接在return后面的表达式并将结果值存入栈顶。
     Top ← Top +1
     Stack[Top] ←表达式的值

  ⒀ 用返回地址标号的下标实现对该标号的转向。
     if addr = i then goto Li