0% found this document useful (0 votes)
202 views5 pages

Java Recursion Concepts and Examples

Uploaded by

Rudranil Lahiri
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
202 views5 pages

Java Recursion Concepts and Examples

Uploaded by

Rudranil Lahiri
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Department of Computer Science: RNSMHS Class XII- Recursion Notes

RECURSION IN JAVA
Recursion in java is a process in which a method calls itself continuously. A method in java
that calls itself is called recursive method.
It makes the code compact but complex to understand.
Syntax:
<access specifier> <returntype> methodname()
{
//code to be executed
methodname();//calling same method
}

Example: Recursive program to find factorial of a number.


public class RecursionExample3
{
static int factorial(int n)
{
if (n == 1) //Base Case
return 1;
else //Recursive Case
return(n * factorial(n-1));
}
public static void main(String[] args)
{
[Link]("Factorial of 5 is: "+factorial(5));
}
}
Base Case: A condition that terminates the calling of the function is called Base Case.
Recursive Case: The condition that calls function repeatedly from its block is called Recursive
Case.

Advantage of Using Recursive Functions:


1. The code may be easier to write.
2. To solve such problems which are naturally recursive such as tower of Hanoi.
3. Reduce unnecessary calling of function.
4. Extremely useful when applying the same solution.
5. Recursion reduce the length of code.
6. It is very useful in solving the data structure problem.
7. Stacks evolutions and infix, prefix, postfix evaluations etc.

Limitation of Using Recursive Functions:


1. Recursive functions are generally slower than non-recursive function.
2. It may require a lot of memory space to hold intermediate results on the system stacks.
3. Hard to analyse or understand the code.
4. It is not more efficient in terms of space and time complexity.
5. The computer may run out of memory if the recursive calls are not properly checked.

1|Page
Department of Computer Science: RNSMHS Class XII- Recursion Notes

Types of Recursive Functions:


1. Direct Recursion:
When a function calls itself within the same function repeatedly, it is called the direct recursion.

Structure of the direct recursion:


fun()
{
// write some code
fun();
// some code
}
In the above structure of the direct recursion, the outer fun() function recursively calls the
inner fun() function, and this type of recursion is called the direct recursion.

Direct Recursion can be further categorized into:

Tail Recursion: If a recursive function calling itself and that recursive call is the last statement
in the function then it’s known as Tail Recursion. After that call the recursive function performs
nothing. The function has to process or perform any operation at the time of calling and it does
nothing at returning time.
Example:
// Java code Showing Tail Recursion
class TailRec {
// Recursion function
static void fun(int n)
{
if (n > 0)
{
[Link](n + " ");

// Last statement in the function


fun(n - 1);
}
}
// Driver Code
public static void main(String[] args)
{
int x = 3;
fun(x);
}
}
Output: 3 2 1

Binary Recursion: In binary recursion, the function calls itself twice in each run. As a result, the
calculation depends on two results from two different recursive calls to itself. If we look at our
Fibonacci sequence generation recursive function, we can easily find that it is a binary
recursion.

2|Page
Department of Computer Science: RNSMHS Class XII- Recursion Notes

Example: Fibonacci Series using Recursion:


public class FibonacciCalc
{
public static int fibRecursion(int count)
{
if (count == 0) {
return 0;
}

if (count == 1 || count == 2) {
return 1;
}

// calling function recursively for nth Fibonacci


return fibRecursion(count - 1) + fibRecursion(count - 2);
}

public static void main(String args[])


{
int fib_len = 9;
[Link]("Fibonacci Series of " + fib_len + " numbers is: \n");

for (int i = 0; i < fib_len; i++) {


[Link](fibRecursion(i) + " ");
}
}
}
Output:
Fibonacci Series of 9 numbers is:
0 1 1 2 3 5 8 13 21

2. Indirect Recursion: In this recursion, there may be more than one functions and they are calling
one another in a circular manner.
Structure of the indirect recursion:
fun1()
{
// write some code
fun2()
}
fun2()
{
// write some code
fun3()
}
fun3()
{
// write some code
fun1()
}

3|Page
Department of Computer Science: RNSMHS Class XII- Recursion Notes

In this structure, there are four functions, fun1(), fun2(), fun3() and fun4(). When the fun1()
function is executed, it calls the fun2() for its execution. And then, the fun2() function starts its
execution calls the fun3() function. In this way, each function leads to another function to
makes their execution circularly. And this type of approach is called indirect recursion.
Example:

// Java program to show Indirect Recursion


import [Link].*;
class IndirectRec{

void funA(int n)
{
if (n > 0) {
[Link](" " +n);

// Fun(A) is calling fun(B)


funB(n - 1);
}
}
void funB(int n)
{
if (n > 1) {
[Link](" " +n);

// Fun(B) is calling fun(A)


funA(n / 2);
}
}

// Driver code
public static void main (String[] args)
{
funA(20);
}
}

• Nested Recursion: In this recursion, a recursive function will pass the parameter as a recursive
call. That means “recursion inside recursion”. Let see the example to understand this
recursion.
Example:
// Java program to show Nested Recursion
import [Link].*;

class NestedRec{
int fun(int n)
{
if (n > 100)
return n - 10;

4|Page
Department of Computer Science: RNSMHS Class XII- Recursion Notes

// A recursive function passing parameter


// as a recursive call or recursion
// inside the recursion
return fun(fun(n + 11));
}

// Driver code
public static void main(String args[])
{
int r;
r = fun(95);
[Link](" "+ r);

}
}

Difference Between Recursion and Iteration:

***************************************************************************

5|Page

Common questions

Powered by AI

Direct recursion occurs when a function calls itself within its own code, such as a factorial calculation function that repeatedly invokes itself with decreased arguments until a base case is met. Indirect recursion involves multiple functions that call each other in a circular manner, such as functions fun1 and fun2 invoking each other in turn until a base condition is met. Indirect recursion can potentially be more complex due to the involvement of multiple function calls .

Recursion is more beneficial than iteration in scenarios where the problem is inherently recursive, making the recursive solution more intuitive and easier to comprehend. Examples include problems like the Tower of Hanoi, tree traversals, and problems involving backtracking. Recursion simplifies the solution by reducing code length and aligning with the natural problem structure, which might be cumbersome to express iteratively .

The base case is crucial as it provides a condition to terminate the recursive calls, preventing the function from calling itself indefinitely. Without a proper base case, the recursion can lead to infinite loops and consequently a stack overflow, as the program continues to use recursion without a stopping point. This highlights the importance of defining a clear base case in every recursive function .

Tail recursion is distinguished by the fact that the recursive call is the last operation in the function. Once the recursive call returns, there is no further computation needed by the invoking function, allowing for optimizations such as tail call optimization (TCO), which can transform the recursion into an iterative process internally. This can lead to more efficient use of resources, unlike non-tail recursion where each call has to maintain state information on the call stack .

Recursion offers several advantages: it makes code easier to write and is useful for naturally recursive problems like the Tower of Hanoi, reduces unnecessary function calling, is concise in terms of code length, and is beneficial for solving certain data structure problems. However, it also has limitations: recursive functions are generally slower than iterative ones, they use more memory space due to storing intermediate results, can be harder to understand and analyze, and are typically less efficient regarding space and time complexity, leading to potential memory exhaustion if not managed properly .

Nested recursion, where a function's argument involves another recursive call, increases complexity and computational cost. It typically results in a significant number of recursive calls, leading to higher memory usage and increased time complexity. Since each call in nested recursion results in multiple invocations, it can be more computationally expensive than other types like tail recursion, which make efficient use of stack space by freeing up memory before returning from a function call .

Binary recursion involves a function calling itself twice in each invocation, as exemplified by the Fibonacci sequence, where the calculation depends on two recursive calls to itself. In contrast, tail recursion occurs when the recursive call is the last action in the function, and direct recursion involves a function calling itself directly within its own code block. Binary recursion typically results in a larger number of calls, making it less space-efficient than tail recursion .

Recursion might be perceived as harder to understand than iteration due to its indirect and less straightforward logic flow, where functions repeatedly call themselves and rely heavily on abstract thinking to trace the execution path. The management of stack frames, the potential for large call hierarchies, and the necessity of properly defined base cases add layers of complexity which can be non-intuitive for programmers accustomed to the more straightforward, linear logic of iterative structures .

Recursive functions pose challenges related to space and time complexity due to the need to store each function's call state on the call stack. This can lead to excessive memory usage, particularly with deep recursion or binary recursion like that seen in the Fibonacci sequence, which results in exponential growth in the number of calls. Furthermore, recursive solutions are often slower because of this overhead and can result in stack overflow errors if the depth of recursion exceeds the stack’s capacity .

Indirect recursion results in complex execution flows as it involves multiple functions calling each other cyclically. This creates intricate call paths that can be difficult to trace and debug. As each function relies on another to proceed, it is essential to have clearly defined base cases and control structures to prevent infinite loops or unintended behavior. Such recursive patterns can complicate understanding and maintenance of the code due to their non-linear execution flow .

You might also like