尾递归

尾递归
Release版本下形如如下的递归代码会被编译器优化:
//  No stack overflow in release version, can be optimized.
void  RecursiveTail( int  i)
{
    RecursiveTail(
++ i);
}

//  Stack overflow, cannot be optimized.
void  RecursiveOver( int  i)
{
    RecursiveOver(i);
    RecursiveOver(i);
}

使用可以被编译器优化的尾递归,不会产生栈溢出,可以提高执行效率。
#include  < stdio.h >

//  递归求阶乘
unsigned  int  Refactorial(unsigned  int  i)
{
    
if (i  ==   0 )
        
return   1 ;
    
return  i  *  Refactorial(i - 1 );
}

//  循环求阶乘
unsigned  int  RefactorialLoop(unsigned  int  i)
{
    
int  r  =   1 ;
    
while (i != 1 )
    {
        r 
*=  i;
        
-- i;
    }
    
return  r;
}

//  尾递归求阶乘
unsigned  int  RefactorialTail(unsigned  int  i, unsigned  int  status)
{
    
if (i  ==   0 )
        
return  status;
    
return  RefactorialTail(i - 1 , status * i);
}

//  递归求菲波纳锲数列
unsigned  int  Febo(unsigned  int  i)
{
    
if (i  <   2 )
        
return  i;
    
return  Febo(i - 1 +  Febo(i - 2 );
}

//  循环求菲波纳锲数列
unsigned  int  FeboLoop(unsigned  int  i)
{
    unsigned 
int  x1  =   1 ;         //  上上次结果
    unsigned  int  x2  =   1 ;         //  上一次结果
    unsigned  int  result  =   1 ;     //  当前结果

    
if (i  <   3 )
        
return   1 ;
        
    
for ( int  j = 3 ; j <= i;  ++ j)
    {
        x1 
=  x2;             // 1, 1, 2
        x2  =  result;         // 1, 2, 3
        result  =  x1  +  x2;     // 2, 3, 5
    }
    
    
return  x1  +  x2;
}

//  尾递归求菲波纳锲数列
unsigned  int  FeboTail(unsigned  int  i, 
                        unsigned 
int  s1,      // 上上次结果
                        unsigned  int  s2)     // 上次结果
{
    
if (i  ==   0 )
        
return  s1;
    
return  FeboTail(i - 1 , s2, s1 + s2);
}

int  main()
{

    unsigned 
int  i  =  Refactorial( 25 );
    printf(
" \n%u\n " , i);
    
    i 
=  RefactorialLoop( 25 );
    printf(
" \n%u\n " , i);
    
    i 
=  RefactorialTail( 25 1 );
    printf(
" \n%u\n " , i);
    
    i 
=  FeboLoop( 45 );
    printf(
" \n%u\n " , i);
    
    i 
=  FeboTail( 45 0 1 );
    printf(
" \n%u\n " , i);
    
return   0 ;
}


你可能感兴趣的:(尾递归)