• 递归转非递归(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



  • 相关阅读:
    什么是Shader
    [Tip: Interface Implementation]
    Focus在某一领域的软件开发 + 在那一领域无限扩展视野
    [Tip: VS]Several IDE Tips and Tricks
    [Tip C# collection]List<Employee> or EmployeeList?
    [Tip Regular expression]Test Regular Expressions With The Regulator
    VS2005设计智能客户端(轉)
    第1章 本书会讨论什么内容
    [导入]关于Sprite.Draw2D
    C#面試(轉)
  • 原文地址:https://www.cnblogs.com/xiaowei-blog/p/3796032.html
Copyright © 2020-2023  润新知