什么是尾递归?
当递归调用是该函数执行的最后一件事时,递归函数就是尾部递归。例如,以下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