递归函数和非递归函数的转变

来源:互联网 发布:破解视频聊天软件 编辑:程序博客网 时间:2024/06/03 13:57

原文链接:http://blog.csdn.net/KKevinnHu/article/details/6756200

递归的定义

       在定义一个过程或函数时出现调用本过程或本函数的成分,称之为递归。若调用自身,称之为直接递归。若过程或函数p调用过程或函数q,而q又调用p,称之为间接递归。

例 求n!(n为正整数) 。

   一般的方法:

  n! = 1*2*…*(n-1)*n

   递归的方法:

    int factorial(int n)

    {    int x;

          if (n==0)

                x=1; 

          else

      x=factorial (n-1)*n;

          return(x); 

    }

   在该函数factorial (n)求解过程中,直接调用factorial (n-1)自身,所以它是一个直接递归函数。

递归模型

      递归模型是递归算法的抽象,它反映递归问题的递归结构,例如,前面的递归算法对应的递归模型如下:

  fun(0)=1       n=0  (1)   fun(n)=n*fun(n-1)  n>0  (2)

     其中:第一个式子给出了递归的终止条件,我们称之为递归出口;第二个式子给出了fun(n)的值与fun(n-1)的值之间的关系,我们称之为递归体。

 

递归算法到非递归算法的转换

      递归算法有两个基本特性:一是递归算法是一种分而治之的、把复杂问题分解为简单问题的求解问题方法,对求解某些复杂问题,递归算法分析问题的方法是十分有效的;二是递归算法的时间/空间效率通常比较差。

      因此,对求解某些问题时,我们希望用递归算法分析问题,用非递归算法具体求解问题。这就需要把递归算法转换为非递归算法。

 

把递归算法转化为非递归算法有如下三种基本方法:

      (1)通过分析,跳过分解过程,直接用循环结构的算法实现求值过程。

      (2)自己用栈模拟系统的运行时栈,通过分析只保存必须保存的信息,从而用非递归算法替代递归算法。

      (3)利用栈保存参数,由于栈的后进先出特性吻合递归算法的执行过程,因而可以用非递归算法替代递归算法。

 1、利用循环跳过分解过程从而消除递归

       采用循环结构消除递归。求解Fibonacci数列的算法如下:

   int Fib(int n)

   {    int i,f1,f2,f3;

         if (n==1 || n==2)  return(n);

         f1=1;f2=2;

         for (i=3;i<=n;i++)

         {    f3=f1+f2;

               f1=f2;f2=f3;

         }

         return(f3);

   }

 

2、模拟系统的运行时栈消除递归

        下面讨论直接使用栈保存中间结果,从而将递归算法转化为非递归算法的过程。

仍以例6.1的递归算法进行讨论,其递归模型有一个递归出口和一个递归体两个式子,分别称为(1)式和(2)式。设计一个栈,其结构如下:

   struct

   {  int vn;    /*保存n值*/

  int vf;    /*保存fun1(n)值*/

  int tag;  /*标识是否求出fun1(n)值,1:未求出,0:已求出*/

   } St[MaxSize];  /*定义栈*/

计算fun1(5)之值的过程如下:

将(5,*,1)进栈;

while (栈不空)

{    if (栈顶元素未计算出栈顶元素的vf值即St[top].tag==1)

     {     if (栈顶元素满足(1)式)

      求出对应的St[top].vf值,并置St[top].tag=0;

                表示已求出对应的函数值;

  else  /*栈顶元素满足(2)式*/

      将(St[top].vn-1,*,1)进栈;

    }

    else if (栈顶元素已计算出栈顶元素的vf值即St[top].tag==0)

          显然栈顶元素由次栈顶元素通过(2)式分解得到的,回过来

          由栈顶元素的vf值计算出次栈顶元素的vf值并退栈;

    if  (栈中只有一个已求出vf值的元素)

        退出循环;

}

St[0].vf即为所求的fun1(n)值;

对应的非递归fun1算法如下:

  int fun1(int n)

  {     top++;        /*初值进栈*/

        St[top].vn=n; St[top].tag=1;

        while (top>-1)        /*栈不空时循环*/

        {           if (St[top].tag==1)    /*未计算出栈顶元素的vf值*/

          {     if (St[top].vn==0)  /*(1)式*/

    {     St[top].vf=1;

          St[top].tag=0;

    }

    else  /*(2)式*/

    {    top++;

          St[top].vn=St[top-1].vn-1; St[top].tag=1;

    }

          }

else if (St[top].tag==0)      /*已计算出vf值*/

              {    St[top-1].vf=St[top-1].vn*St[top].vf;  /*(2)式*/

        St[top-1].tag=0;

        top--;

                }

  /*栈中只有一个已求出vf的元素时退出循环*/

                        if (top==0 && St[top].tag==0)

      break;

  }

  return(St[top].vf);

    }


0 0
原创粉丝点击