📜  尾递归

📅  最后修改于: 2021-05-08 18:27:17             🧑  作者: Mango

什么是尾递归?
当递归调用是该函数执行的最后一件事时,递归函数就是尾部递归。例如,以下C++函数print()是尾递归的。

C
// An example of tail recursive function
void print(int n)
{
    if (n < 0)  return;
    cout << " " << n;
 
    // The last executed statement is recursive call
    print(n-1);
}


Java
// An example of tail recursive function
static void print(int n)
{
    if (n < 0)
      return;
    
    System.out.print(" " + n);
    
    // The last executed statement
      // is recursive call
    print(n - 1);
}
 
// This code is contributed by divyeh072019


Python3
# An example of tail recursive function
def prints(n):
 
    if (n < 0):
        return
    print(" " + str(n),end='')
 
    # The last executed statement is recursive call
    prints(n-1)
     
    # This code is contributed by Pratham76


C#
// An example of tail recursive function
static void print(int n)
{
    if (n < 0)
      return;
   
    Console.Write(" " + n);
   
    // The last executed statement
      // is recursive call
    print(n - 1);
}
 
// This code is contributed by divyeshrabadiya07


C++
#include
using namespace std;
 
// A NON-tail-recursive function.  The function is not tail
// recursive because the value returned by fact(n-1) is used in
// fact(n) and call to fact(n-1) is not the last thing done by fact(n)
unsigned int fact(unsigned int n)
{
    if (n == 0) return 1;
 
    return n*fact(n-1);
}
 
// Driver program to test above function
int main()
{
    cout << fact(5);
    return 0;
}


Java
class GFG {
     
    // A NON-tail-recursive function.
    // The function is not tail
    // recursive because the value
    // returned by fact(n-1) is used
    // in fact(n) and call to fact(n-1)
    // is not the last thing done by
    // fact(n)
    static int fact(int n)
    {
        if (n == 0) return 1;
     
        return n*fact(n-1);
    }
     
    // Driver program
    public static void main(String[] args)
    {
        System.out.println(fact(5));
    }
}
 
// This code is contributed by Smitha.


Python3
# A NON-tail-recursive function.
# The function is not tail
# recursive because the value
# returned by fact(n-1) is used
# in fact(n) and call to fact(n-1)
# is not the last thing done by
# fact(n)
def fact(n):
 
    if (n == 0):
        return 1
 
    return n * fact(n-1)
 
# Driver program to test
# above function
print(fact(5))
# This code is contributed by Smitha.


C#
using System;
 
class GFG {
     
    // A NON-tail-recursive function.
    // The function is not tail
    // recursive because the value
    // returned by fact(n-1) is used
    // in fact(n) and call to fact(n-1)
    // is not the last thing done by
    // fact(n)
    static int fact(int n)
    {
        if (n == 0)
            return 1;
     
        return n * fact(n-1);
    }
     
    // Driver program to test
    // above function
    public static void Main()
    {
        Console.Write(fact(5));
    }
}
 
// This code is contributed by Smitha


PHP


Javascript


C++
#include
using namespace std;
 
// A tail recursive function to calculate factorial
unsigned factTR(unsigned int n, unsigned int a)
{
    if (n == 0)  return a;
 
    return factTR(n-1, n*a);
}
 
// A wrapper over factTR
unsigned int fact(unsigned int n)
{
   return factTR(n, 1);
}
 
// Driver program to test above function
int main()
{
    cout << fact(5);
    return 0;
}


Java
// Java Code for Tail Recursion
 
class GFG {
     
    // A tail recursive function
    // to calculate factorial
    static int factTR(int n, int a)
    {
        if (n == 0)
            return a;
     
        return factTR(n - 1, n * a);
    }
     
    // A wrapper over factTR
    static int fact(int n)
    {
        return factTR(n, 1);
    }
 
    // Driver code
    static public void main (String[] args)
    {
        System.out.println(fact(5));
    }
}
 
// This code is contributed by Smitha.


Python3
# A tail recursive function
# to calculate factorial
def fact(n, a = 1):
 
    if (n == 0):
        return a
 
    return fact(n - 1, n * a)
 
# Driver program to test
#  above function
print(fact(5))
 
# This code is contributed
# by Smitha
# "improved by Ujwal"


C#
// C# Code for Tail Recursion
using System;
 
class GFG {
     
    // A tail recursive function
    // to calculate factorial
    static int factTR(int n, int a)
    {
        if (n == 0)
            return a;
     
        return factTR(n - 1, n * a);
    }
     
    // A wrapper over factTR
    static int fact(int n)
    {
        return factTR(n, 1);
    }
 
    // Driver code
    static public void Main ()
    {
        Console.WriteLine(fact(5));
    }
}
 
// This code is contributed by Ajit.


PHP


Javascript


我们为什么要在乎?
被认为比非尾递归函数更好的尾递归函数,因为可以通过编译器优化尾递归。编译器用来优化尾递归函数的想法很简单,因为递归调用是最后一条语句,所以在当前函数没什么可做的,因此保存当前函数的堆栈框架是没有用的(有关更多信息,请参阅本文)细节)。

可以将非尾递归函数编写为尾递归以对其进行优化吗?
考虑以下函数来计算n的阶乘。这是一个非尾递归函数。尽管乍一看看起来像是尾部递归。如果仔细观察,我们可以看到事实(n-1)返回的值已在事实(n)中使用,因此对事实(n-1)的调用并不是事实(n)完成的最后一件事

C++

#include
using namespace std;
 
// A NON-tail-recursive function.  The function is not tail
// recursive because the value returned by fact(n-1) is used in
// fact(n) and call to fact(n-1) is not the last thing done by fact(n)
unsigned int fact(unsigned int n)
{
    if (n == 0) return 1;
 
    return n*fact(n-1);
}
 
// Driver program to test above function
int main()
{
    cout << fact(5);
    return 0;
}

Java

class GFG {
     
    // A NON-tail-recursive function.
    // The function is not tail
    // recursive because the value
    // returned by fact(n-1) is used
    // in fact(n) and call to fact(n-1)
    // is not the last thing done by
    // fact(n)
    static int fact(int n)
    {
        if (n == 0) return 1;
     
        return n*fact(n-1);
    }
     
    // Driver program
    public static void main(String[] args)
    {
        System.out.println(fact(5));
    }
}
 
// This code is contributed by Smitha.

Python3

# A NON-tail-recursive function.
# The function is not tail
# recursive because the value
# returned by fact(n-1) is used
# in fact(n) and call to fact(n-1)
# is not the last thing done by
# fact(n)
def fact(n):
 
    if (n == 0):
        return 1
 
    return n * fact(n-1)
 
# Driver program to test
# above function
print(fact(5))
# This code is contributed by Smitha.

C#

using System;
 
class GFG {
     
    // A NON-tail-recursive function.
    // The function is not tail
    // recursive because the value
    // returned by fact(n-1) is used
    // in fact(n) and call to fact(n-1)
    // is not the last thing done by
    // fact(n)
    static int fact(int n)
    {
        if (n == 0)
            return 1;
     
        return n * fact(n-1);
    }
     
    // Driver program to test
    // above function
    public static void Main()
    {
        Console.Write(fact(5));
    }
}
 
// This code is contributed by Smitha

的PHP


Java脚本


输出 :

120

上面的函数可以写成尾递归函数。想法是再使用一个参数,并在第二个参数中累积阶乘值。当n达到0时,返回累加值。

C++

#include
using namespace std;
 
// A tail recursive function to calculate factorial
unsigned factTR(unsigned int n, unsigned int a)
{
    if (n == 0)  return a;
 
    return factTR(n-1, n*a);
}
 
// A wrapper over factTR
unsigned int fact(unsigned int n)
{
   return factTR(n, 1);
}
 
// Driver program to test above function
int main()
{
    cout << fact(5);
    return 0;
}

Java

// Java Code for Tail Recursion
 
class GFG {
     
    // A tail recursive function
    // to calculate factorial
    static int factTR(int n, int a)
    {
        if (n == 0)
            return a;
     
        return factTR(n - 1, n * a);
    }
     
    // A wrapper over factTR
    static int fact(int n)
    {
        return factTR(n, 1);
    }
 
    // Driver code
    static public void main (String[] args)
    {
        System.out.println(fact(5));
    }
}
 
// This code is contributed by Smitha.

Python3

# A tail recursive function
# to calculate factorial
def fact(n, a = 1):
 
    if (n == 0):
        return a
 
    return fact(n - 1, n * a)
 
# Driver program to test
#  above function
print(fact(5))
 
# This code is contributed
# by Smitha
# "improved by Ujwal"

C#

// C# Code for Tail Recursion
using System;
 
class GFG {
     
    // A tail recursive function
    // to calculate factorial
    static int factTR(int n, int a)
    {
        if (n == 0)
            return a;
     
        return factTR(n - 1, n * a);
    }
     
    // A wrapper over factTR
    static int fact(int n)
    {
        return factTR(n, 1);
    }
 
    // Driver code
    static public void Main ()
    {
        Console.WriteLine(fact(5));
    }
}
 
// This code is contributed by Ajit.

的PHP


Java脚本


输出 :

120