相互递归是变异递归。如果第一个函数对第二个函数进行递归调用,而第二个函数又调用第一个函数,则将两个函数称为相互递归。
在软件开发中,此概念以循环依赖关系使用,循环依赖关系是两个或多个直接或间接依赖彼此以函数运行的模块之间的关系。这样的模块也称为相互递归。
相互递归的一个很好的例子是实现Hofstadter序列。
霍夫斯塔德序列
在数学中,霍夫斯塔特序列是由非线性递归关系定义的一组相关整数序列的成员。在此示例中,我们将重点介绍霍夫施塔特女性和男性序列:
C++
// C++ program to implement Hofstader Sequence
// using mutual recursion
#include
using namespace std;
int hofstaderFemale(int);
int hofstaderMale(int);
// Female function
int hofstaderFemale(int n)
{
if (n < 0)
return 0;
else
if (n == 0)
return 1;
else
return (n - hofstaderFemale(n - 1));
}
// Male function
int hofstaderMale(int n)
{
if (n < 0)
return 0;
else
if (n == 0)
return 0;
else
return (n - hofstaderMale(n - 1));
}
// Driver Code
int main()
{
int i;
cout << "F: ";
for (i = 0; i < 20; i++)
cout << hofstaderFemale(i) << " ";
cout << "\n";
cout << "M: ";
for (i = 0; i < 20; i++)
cout << hofstaderMale(i)<< " ";
return 0;
}
// This code is contributed by shubhamsingh10
C
// C program to implement Hofstader Sequence
// using mutual recursion
#include
int hofstaderFemale(int);
int hofstaderMale(int);
// Female function
int hofstaderFemale(int n)
{
if (n < 0)
return;
else
return (n == 0) ? 1 : n - hofstaderFemale(n - 1);
}
// Male function
int hofstaderMale(int n)
{
if (n < 0)
return;
else
return (n == 0) ? 0 : n - hofstaderMale(n - 1);
}
// hard coded driver function to run the program
int main()
{
int i;
printf("F: ");
for (i = 0; i < 20; i++)
printf("%d ", hofstaderFemale(i));
printf("\n");
printf("M: ");
for (i = 0; i < 20; i++)
printf("%d ", hofstaderMale(i));
return 0;
}
Java
// Java program to implement Hofstader
// Sequence using mutual recursion
import java .io.*;
class GFG {
// Female function
static int hofstaderFemale(int n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 1 : n -
hofstaderFemale(n - 1);
}
// Male function
static int hofstaderMale(int n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 0 : n -
hofstaderMale(n - 1);
}
// Driver Code
static public void main (String[] args)
{
int i;
System.out.print("F: ");
for (i = 0; i < 20; i++)
System.out.print(hofstaderFemale(i)
+ " ");
System.out.println();
System.out.print("M: ");
for (i = 0; i < 20; i++)
System.out.print(hofstaderMale(i)
+ " ");
}
}
// This code is contributed by anuj_67.
Python3
# Python program to implement
# Hofstader Sequence using
# mutual recursion
# Female function
def hofstaderFemale(n):
if n < 0:
return;
else:
val = 1 if n == 0 else (
n - hofstaderFemale(n - 1))
return val
# Male function
def hofstaderMale(n):
if n < 0:
return;
else:
val = 0 if n == 0 else (
n - hofstaderMale(n - 1))
return val
# Driver code
print("F:", end = " ")
for i in range(0, 20):
print(hofstaderFemale(i), end = " ")
print("\n")
print("M:", end = " ")
for i in range(0, 20):
print(hofstaderMale(i), end = " ")
# This code is contributed
# by Shantanu Sharma
C#
// C# program to implement Hofstader
// Sequence using mutual recursion
using System;
class GFG {
// Female function
static int hofstaderFemale(int n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 1 : n -
hofstaderFemale(n - 1);
}
// Male function
static int hofstaderMale(int n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 0 : n -
hofstaderMale(n - 1);
}
// Driver Code
static public void Main ()
{
int i;
Console.WriteLine("F: ");
for (i = 0; i < 20; i++)
Console.Write(hofstaderFemale(i) + " ");
Console.WriteLine();
Console.WriteLine("M: ");
for (i = 0; i < 20; i++)
Console.Write(hofstaderMale(i) + " ");
}
}
// This code is contributed by Ajit.
PHP
Output:
F: 1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9
M: 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10
循环依赖/相互递归的缺点:
- 当一个模块中的一小部分本地更改扩展到其他模块并产生有害的全局影响时,循环依赖项可能会导致多米诺效应
- 循环依赖关系还可能导致无限递归或其他意外失败。
- 循环依赖关系还可以通过阻止某些非常原始的自动垃圾收集器(使用引用计数的垃圾收集器)释放未使用的对象来导致内存泄漏。
参考:维基百科