Mutual recursion is a variation recursion. Two functions are called mutually recursive if the first function makes a recursive call to the second function and the second function, in turn, calls the first one.
In software development, this concept is used in circular dependency which is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive.
A great example of mutual recursion would be implementing the Hofstadter Sequence.
Hofstadter Sequence
In mathematics, a Hofstadter sequence is a member of a family of related integer sequences defined by non-linear recurrence relations. In this example we are going to focus on Hofstadter Female and Male sequences:
[Tex]M ( 0 ) = 0[/Tex]
C++
#include <bits/stdc++.h>
using namespace std;
int hofstadterFemale( int );
int hofstadterMale( int );
int hofstadterFemale( int n)
{
if (n < 0)
return 0;
else
if (n == 0)
return 1;
else
return (n - hofstadterFemale(n - 1));
}
int hofstadterMale( int n)
{
if (n < 0)
return 0;
else
if (n == 0)
return 0;
else
return (n - hofstadterMale(n - 1));
}
int main()
{
int i;
cout << "F: " ;
for (i = 0; i < 20; i++)
cout << hofstadterFemale(i) << " " ;
cout << "\n" ;
cout << "M: " ;
for (i = 0; i < 20; i++)
cout << hofstadterMale(i)<< " " ;
return 0;
}
|
C
#include <stdio.h>
int hofstaderFemale( int );
int hofstaderMale( int );
int hofstaderFemale( int n)
{
if (n < 0)
return ;
else
return (n == 0) ? 1 : n - hofstaderFemale(n - 1);
}
int hofstaderMale( int n)
{
if (n < 0)
return ;
else
return (n == 0) ? 0 : n - hofstaderMale(n - 1);
}
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
import java .io.*;
class GFG {
static int hofstaderFemale( int n)
{
if (n < 0 )
return 0 ;
else
return (n == 0 ) ? 1 : n -
hofstaderFemale(n - 1 );
}
static int hofstaderMale( int n)
{
if (n < 0 )
return 0 ;
else
return (n == 0 ) ? 0 : n -
hofstaderMale(n - 1 );
}
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)
+ " " );
}
}
|
Python3
def hofstaderFemale(n):
if n < 0 :
return ;
else :
val = 1 if n = = 0 else (
n - hofstaderFemale(n - 1 ))
return val
def hofstaderMale(n):
if n < 0 :
return ;
else :
val = 0 if n = = 0 else (
n - hofstaderMale(n - 1 ))
return val
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 = " " )
|
C#
using System;
class GFG {
static int hofstaderFemale( int n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 1 : n -
hofstaderFemale(n - 1);
}
static int hofstaderMale( int n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 0 : n -
hofstaderMale(n - 1);
}
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) + " " );
}
}
|
PHP
<?php
function hofstaderFemale( $n )
{
if ( $n < 0)
return ;
else
return ( $n == 0) ? 1 : $n - hofstaderFemale( $n - 1);
}
function hofstaderMale( $n )
{
if ( $n < 0)
return ;
else
return ( $n == 0) ? 0 : $n - hofstaderMale( $n - 1);
}
$i ;
echo "F: " ;
for ( $i = 0; $i < 20; $i ++)
echo hofstaderFemale( $i ), " " ;
echo "\n" ;
echo "M: " ;
for ( $i = 0; $i < 20; $i ++)
echo hofstaderMale( $i ), " " ;
?>
|
Javascript
<script>
function hofstaderFemale(n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 1 :
n - hofstaderFemale(n - 1);
}
function hofstaderMale(n)
{
if (n < 0)
return 0;
else
return (n == 0) ? 0 :
n - hofstaderMale(n - 1);
}
let i;
document.write( "F: " );
for (i = 0; i < 20; i++)
document.write(hofstaderFemale(i) + " " );
document.write( "</br>" );
document.write( "M: " );
for (i = 0; i < 20; i++)
document.write(hofstaderMale(i) + " " );
</script>
|
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
Disadvantages of Circular Dependency/Mutual Recursion:
- Circular dependencies can cause a domino effect when a small local change in one module spreads into other modules and has unwanted global effects
- Circular dependencies can also result in infinite recursions or other unexpected failures.
- Circular dependencies may also cause memory leaks by preventing certain very primitive automatic garbage collectors (those that use reference counting) from deallocating unused objects.
References: Wikipedia
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!