什么是递归?
函数直接或间接调用自身的过程称为递归,而相应的函数称为递归函数。使用递归算法,可以很容易地解决某些问题。此类问题的示例包括河内塔(TOH),有序/预排序/后序树遍历,图的DFS等。
数学解释
让我们考虑一个问题,程序员必须确定前n个自然数之和,有几种方法可以做到这一点,但是最简单的方法是简单地将1到n之间的数字相加。因此,该函数看起来就像
approach(1) – Simply adding one by one
f(n) = 1 + 2 + 3 +……..+ n
但是还有另一种数学方法来表示这一点,
approach(2) – Recursive adding
f(n) = 1 n=1
f(n) = n + f(n-1) n>1
方法(1)和方法(2)之间有一个简单的区别,即在方法(2)中,函数“ f() ”本身在函数内部被调用,因此此现象称为递归,并且函数包含递归称为递归函数,最后这是程序员手中一个很好的工具,它可以以更轻松,更有效的方式对一些问题进行编码。
递归的基本条件是什么?
在递归程序中,提供了对基本情况的解决方案,并且以较小的问题表示较大的问题的解决方案。
int fact(int n)
{
if (n < = 1) // base case
return 1;
else
return n*fact(n-1);
}
在上面的示例中,定义了n <= 1的基本情况,并且可以通过转换为较小的1直至达到基本情况来解决较大的数值。
如何使用递归解决特定问题?
这个想法是用一个或多个较小的问题来表示一个问题,并添加一个或多个停止递归的基本条件。例如,如果我们知道(n-1)的阶乘,就可以计算阶乘n。阶乘的基本情况为n =0。当n = 0时,我们返回1。
为什么在递归中发生堆栈溢出错误?
如果未达到或未定义基本情况,则可能会出现堆栈溢出问题。让我们以一个例子来理解这一点。
int fact(int n)
{
// wrong base case (it may cause
// stack overflow).
if (n == 100)
return 1;
else
return n*fact(n-1);
}
如果调用fact(10),它将调用fact(9),fact(8),fact(7)等,但数量永远不会达到100。因此,不会达到基本情况。如果堆栈上的这些功能耗尽了内存,则会导致堆栈溢出错误。
直接和间接递归有什么区别?
如果函数调用相同的函数,则称为直接递归。如果fun函数调用另一个函数,例如fun_new和fun_new直接或间接调用fun,则该函数称为间接递归。表1说明了直接和间接递归之间的区别。
// An example of direct recursion
void directRecFun()
{
// Some code....
directRecFun();
// Some code...
}
// An example of indirect recursion
void indirectRecFun1()
{
// Some code...
indirectRecFun2();
// Some code...
}
void indirectRecFun2()
{
// Some code...
indirectRecFun1();
// Some code...
}
尾递归和非尾递归之间有什么区别?
当递归调用是该函数执行的最后一件事时,递归函数就是尾部递归。有关详细信息,请参阅尾递归文章。
如何在递归中将内存分配给不同的函数调用?
从main()调用任何函数,都会在堆栈上为其分配内存。递归函数调用自身,被调用函数的内存分配在分配给调用函数的内存之上,并且为每个函数调用创建不同的局部变量副本。当达到基本情况时,该函数将其值返回给调用该函数,并取消分配内存,然后过程继续进行。
让我们以一个简单的函数为例,说明递归的工作原理。
CPP
// A C++ program to demonstrate working of
// recursion
#include
using namespace std;
void printFun(int test)
{
if (test < 1)
return;
else {
cout << test << " ";
printFun(test - 1); // statement 2
cout << test << " ";
return;
}
}
// Driver Code
int main()
{
int test = 3;
printFun(test);
}
Java
// A Java program to demonstrate working of
// recursion
class GFG {
static void printFun(int test)
{
if (test < 1)
return;
else {
System.out.printf("%d ", test);
printFun(test - 1); // statement 2
System.out.printf("%d ", test);
return;
}
}
// Driver Code
public static void main(String[] args)
{
int test = 3;
printFun(test);
}
}
// This code is contributed by
// Smitha Dinesh Semwal
Python3
# A Python 3 program to
# demonstrate working of
# recursion
def printFun(test):
if (test < 1):
return
else:
print(test, end=" ")
printFun(test-1) # statement 2
print(test, end=" ")
return
# Driver Code
test = 3
printFun(test)
# This code is contributed by
# Smitha Dinesh Semwal
C#
// A C# program to demonstrate
// working of recursion
using System;
class GFG {
// function to demonstrate
// working of recursion
static void printFun(int test)
{
if (test < 1)
return;
else {
Console.Write(test + " ");
// statement 2
printFun(test - 1);
Console.Write(test + " ");
return;
}
}
// Driver Code
public static void Main(String[] args)
{
int test = 3;
printFun(test);
}
}
// This code is contributed by Anshul Aggarwal.
PHP
Javascript
C++
// C++ code to implement Fibonacci series
#include
using namespace std;
// Function for fibonacci
int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
int main()
{
// Initialize variable n.
int n = 5;
cout<<"Fibonacci series of 5 numbers is: ";
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++)
{
cout<
C
// C code to implement Fibonacci series
#include
// Function for fibonacci
int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
int main()
{
// Initialize variable n.
int n = 5;
printf("Fibonacci series "
"of %d numbers is: ",
n);
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++) {
printf("%d ", fib(i));
}
return 0;
}
Java
// Java code to implement Fibonacci series
import java.util.*;
class GFG
{
// Function for fibonacci
static int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
public static void main(String []args)
{
// Initialize variable n.
int n = 5;
System.out.print("Fibonacci series of 5 numbers is: ");
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++)
{
System.out.print(fib(i)+" ");
}
}
}
// This code is contributed by rutvik_56.
Python3
# Python code to implement Fibonacci series
# Function for fibonacci
def fib(n):
# Stop condition
if (n == 0):
return 0
# Stop condition
if (n == 1 or n == 2):
return 1
# Recursion function
else:
return (fib(n - 1) + fib(n - 2))
# Driver Code
# Initialize variable n.
n = 5;
print("Fibonacci series of 5 numbers is :",end=" ")
# for loop to print the fiboancci series.
for i in range(0,n):
print(fib(i),end=" ")
C#
using System;
public class GFG
{
// Function for fibonacci
static int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
static public void Main ()
{
// Initialize variable n.
int n = 5;
Console.Write("Fibonacci series of 5 numbers is: ");
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++)
{
Console.Write(fib(i) + " ");
}
}
}
// This code is contributed by avanitrachhadiya2155
Javascript
C++
// C++ code to implement factorial
#include
using namespace std;
// Factorial function
int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
int main()
{
int n = 5;
cout<<"factorial of "<
C
// C code to implement factorial
#include
// Factorial function
int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
int main()
{
int n = 5;
printf("factorial of %d is: %d", n, f(n));
return 0;
}
Java
// Java code to implement factorial
public class GFG
{
// Factorial function
static int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
public static void main(String[] args)
{
int n = 5;
System.out.println("factorial of " + n + " is: " + f(n));
}
}
// This code is contributed by divyesh072019.
Python3
# Python3 code to implement factorial
# Factorial function
def f(n):
# Stop condition
if (n == 0 or n == 1):
return 1;
# Recursive condition
else:
return n * f(n - 1);
# Driver code
if __name__=='__main__':
n = 5;
print("factorial of",n,"is:",f(n))
# This code is contributed by pratham76.
C#
// C# code to implement factorial
using System;
class GFG {
// Factorial function
static int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
static void Main()
{
int n = 5;
Console.WriteLine("factorial of " + n + " is: " + f(n));
}
}
// This code is contributed by divyeshrabadiya07.
Javascript
输出 :
3 2 1 1 2 3
当从main()调用printFun(3)时,将内存分配给printFun(3),并将局部变量test初始化为3,并将语句1到4压入堆栈,如下图所示。它首先打印“ 3”。在语句2中,调用printFun(2)并将内存分配给printFun(2),并将局部变量test初始化为2,并将语句1至4压入堆栈。同样, printFun(2)调用printFun(1),而printFun(1)调用printFun(0) 。 printFun(0)转到if语句,然后返回到printFun(1) 。执行剩余的printFun(1)语句,并返回到printFun(2) ,依此类推。在输出中,从3到1的值被打印,然后从1到3的值被打印。下图显示了内存堆栈。
现在,让我们讨论一些可以通过使用递归解决的实际问题,并了解其基本工作原理。为了基本了解,请阅读以下文章。
对递归的基本了解。
问题1:编写程序和递归关系以找到n的斐波那契数列,其中n> 2。
数学方程式:
n if n == 0, n == 1;
fib(n) = fib(n-1) + fib(n-2) otherwise;
递归关系:
T(n) = T(n-1) + T(n-2) + O(1)
递归程序:
Input: n = 5
Output:
Fibonacci series of 5 numbers is : 0 1 1 2 3
执行:
C++
// C++ code to implement Fibonacci series
#include
using namespace std;
// Function for fibonacci
int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
int main()
{
// Initialize variable n.
int n = 5;
cout<<"Fibonacci series of 5 numbers is: ";
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++)
{
cout<
C
// C code to implement Fibonacci series
#include
// Function for fibonacci
int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
int main()
{
// Initialize variable n.
int n = 5;
printf("Fibonacci series "
"of %d numbers is: ",
n);
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++) {
printf("%d ", fib(i));
}
return 0;
}
Java
// Java code to implement Fibonacci series
import java.util.*;
class GFG
{
// Function for fibonacci
static int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
public static void main(String []args)
{
// Initialize variable n.
int n = 5;
System.out.print("Fibonacci series of 5 numbers is: ");
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++)
{
System.out.print(fib(i)+" ");
}
}
}
// This code is contributed by rutvik_56.
Python3
# Python code to implement Fibonacci series
# Function for fibonacci
def fib(n):
# Stop condition
if (n == 0):
return 0
# Stop condition
if (n == 1 or n == 2):
return 1
# Recursion function
else:
return (fib(n - 1) + fib(n - 2))
# Driver Code
# Initialize variable n.
n = 5;
print("Fibonacci series of 5 numbers is :",end=" ")
# for loop to print the fiboancci series.
for i in range(0,n):
print(fib(i),end=" ")
C#
using System;
public class GFG
{
// Function for fibonacci
static int fib(int n)
{
// Stop condition
if (n == 0)
return 0;
// Stop condition
if (n == 1 || n == 2)
return 1;
// Recursion function
else
return (fib(n - 1) + fib(n - 2));
}
// Driver Code
static public void Main ()
{
// Initialize variable n.
int n = 5;
Console.Write("Fibonacci series of 5 numbers is: ");
// for loop to print the fiboancci series.
for (int i = 0; i < n; i++)
{
Console.Write(fib(i) + " ");
}
}
}
// This code is contributed by avanitrachhadiya2155
Java脚本
Fibonacci series of 5 numbers is: 0 1 1 2 3
这是输入5的递归树,它清楚地显示了如何将大问题解决为较小的问题。
fib(n)是斐波那契函数。给定程序的时间复杂度可能取决于函数调用。
fib(n) -> level CBT (UB) -> 2^n-1 nodes -> 2^n function call -> 2^n*O(1) -> T(n) = O(2^n)
为最好的情况。
T(n) = θ(2^n\2)
在职的:
问题2:编写程序和递归关系以找到n的阶乘,其中n> 2。
数学方程:
1 if n == 0 or n == 1;
f(n) = n*f(n-1) if n> 1;
递归关系:
T(n) = 1 for n = 0
T(n) = 1 + T(n-1) for n > 0
递归程序:
输入: n = 5
输出:
5的阶乘是:120
执行:
C++
// C++ code to implement factorial
#include
using namespace std;
// Factorial function
int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
int main()
{
int n = 5;
cout<<"factorial of "<
C
// C code to implement factorial
#include
// Factorial function
int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
int main()
{
int n = 5;
printf("factorial of %d is: %d", n, f(n));
return 0;
}
Java
// Java code to implement factorial
public class GFG
{
// Factorial function
static int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
public static void main(String[] args)
{
int n = 5;
System.out.println("factorial of " + n + " is: " + f(n));
}
}
// This code is contributed by divyesh072019.
Python3
# Python3 code to implement factorial
# Factorial function
def f(n):
# Stop condition
if (n == 0 or n == 1):
return 1;
# Recursive condition
else:
return n * f(n - 1);
# Driver code
if __name__=='__main__':
n = 5;
print("factorial of",n,"is:",f(n))
# This code is contributed by pratham76.
C#
// C# code to implement factorial
using System;
class GFG {
// Factorial function
static int f(int n)
{
// Stop condition
if (n == 0 || n == 1)
return 1;
// Recursive condition
else
return n * f(n - 1);
}
// Driver code
static void Main()
{
int n = 5;
Console.WriteLine("factorial of " + n + " is: " + f(n));
}
}
// This code is contributed by divyeshrabadiya07.
Java脚本
factorial of 5 is: 120
在职的:
与迭代编程相比,递归编程有哪些缺点?
请注意,递归程序和迭代程序都具有相同的解决问题的能力,即,每个递归程序都可以迭代地编写,反之亦然。递归程序比迭代程序具有更大的空间要求,因为所有功能都将保留在堆栈中,直到达到基本情况为止。由于函数调用和返回开销,它也有更多的时间要求。
递归编程比迭代编程有什么优势?
递归提供了一种干净且简单的编写代码的方法。有些问题本质上是递归的,例如遍历树,河内塔等。对于此类问题,最好编写递归代码。我们还可以借助堆栈数据结构来迭代地编写此类代码。例如,请参阅“无递归的有序树遍历,河内迭代塔”。