Javatpoint Logo
Javatpoint Logo

Recursive Algorithm

Recursive issues are common in competitive programming. And you will first develop recursive logic for them before attempting to tackle these issues utilizing various programming paradigms. Recursive thinking is a crucial part of programming. It helps you divide up complicated tasks into simpler ones. As a result, it is often used in practically all programming languages.

What is Recursion?

Recursion is the action of a function calling itself either directly or indirectly, and the associated function is known as a recursive function. A recursive method can be used to tackle some issues with relative ease. Towers of Hanoi (TOH), in order/preorder/postorder tree traversals, DFS of Graph, etc., are a few examples of these issues. By calling a duplicate of itself and resolving the original problem's smaller subproblems, a recursive function solves a specific problem. As and when necessary, many additional recursive calls can be produced. It is crucial to understand that we must present a specific situation to stop this recursion process. Therefore, each time, the function calls itself a simplified version of the initial issue.

A recursive algorithm calls itself with smaller input values and, after performing basic operations on the returned value for the minor input, provides the result for the current input. A recursive method can solve a problem if smaller versions of the same problem can be solved by applying solutions to them, and the smaller versions decrease to easily solvable examples.

You will split the provided problem statement into two pieces to construct a recursive algorithm. The primary case is the first, and the recursive step is the second.

  • Base Case: This is the simplest possible solution to the issue, consisting only of a condition that ends the recursive function. When a specific condition is satisfied, the result is evaluated in this base case.
  • Recursive Step: It calculates the outcome by making repeated calls to the same function but with more minor or straightforward inputs.

Recursion Required for:

Recursion is a fantastic approach that allows us to shorten our code and simplify understanding and writing. Compared to the iteration approach, it offers a few benefits that will be covered later. Recursion is one of the finest ways to complete a work that its related subtasks may describe. The factorial of a number, for instance.

Characteristics of Recursion

Recursion's characteristics include:

  • Repeating the same actions with different inputs.
  • To make the issue smaller at each phase, we experiment with smaller inputs.
  • A base condition must stop the recursion; otherwise, an infinite loop would result.

Steps in an Algorithm

The following algorithmic steps are used to implement recursion in a function:

  1. Step 1: Establish a primary case. Choose the most straightforward situation for which the answer is obvious or trivial. This is the recursion's halting condition, which stops the function from indefinitely calling itself.
  2. Define a recursive case in step two: Describe the issue in terms of its smaller counterparts. Recursively calling the function will allow you to solve each subproblem by breaking the problem up into smaller versions of itself.
  3. Step 3: Verify that the recursion ends: Make sure the recursive code does not go into an infinite loop and ultimately reaches the base case.
  4. Step 4: Combine the solutions. To answer the main problem, combine the solutions to the subproblems.

An Interpretation in Mathematics

Let's look at a situation where a programmer has to get the sum of the first n natural numbers. There are a few methods for achieving this, but the easiest one is to add the integers from 1 to n. Therefore, the function is represented mathematically as follows: approach(1) - Simply adding one at a time f(n) = 1 + 2 + 3 +........+ n yet there is another way to describe this: approach(2) - Recursive addition f(n) = 1 n=1 f(n) = n + f(n-1) n>1

The only difference between approaches (1) and (2) is that in approach (2), the function "f()" is called within the function. This phenomenon is known as recursion, and the function that contains recursion is known as a recursive function. In the end, this is an excellent tool for programmers to code some problems more straightforwardly and effectively.

Recursive functions are stored in memory in what manner?

Recursion consumes additional memory because the recursive function adds to the stack with each call and stores the items there until the call is concluded. Like the stack data structure, the recursive function uses the LIFO (LAST IN FIRST OUT) structure.

What defines the recursive base condition?

The base case solution is given in the recursive program, and the more significant problem's solution is given in terms of more minor issues.

The base case for n = 1 is described in the example mentioned earlier, and the more excellent value of a number may be addressed by downsizing it until the base case is attained.

How is recursion used to tackle a specific problem?

The goal is to break a more significant problem down into a more minor one, then add a base condition or conditions to stop the recursion. For instance, if we know the factorial of (n-1), we may compute factorial n. Factorial's primary case would be n = 0. If n equals 0, we return 1.

Why does recursion lead to a stack overflow error?

The stack overflow issue may occur if the base case is not reached or defined. To further grasp this, let's look at an example.

If fact(10) is called, fact(9), fact(8), fact(7), and so forth will also be called, but the total will always be 100. The primary case still needs to be achieved. A stack overflow fault will occur if these functions on the stack fill up all available memory.

What distinguishes direct from indirect recursion?

If a function calls another function named fun, that function is said to be direct recursive. If a function fun calls another function, like fun_new, and fun_new calls fun either directly or indirectly, that function is said to be indirectly recursive. Table 1 presents an illustration of the distinction between direct and indirect recursion.

What distinguishes tailed from non-tailed recursion?

When a recursive call is the function's final action, it is said to be tail recursive. For more information, see the article on tail recursion.

How does recursion distribute memory to various function calls?

Any function is given memory on the stack when called from main(). Every time a recursive function calls itself, a new copy of the local variables is made, and memory is allocated for the called function on top of the memory allocated for the calling function. When the function reaches the base case, memory is released, and the process continues, delivering its value to the function from which it was called.

Let's use a straightforward function to demonstrate how recursion functions.

Allocation of Memory for Recursive Method

The function is generated in fresh stack memory copies with each recursive call. The copy is removed from storage once the operation returns some data. Because all arguments and other variables specified inside functions are retained on the stack, each recursive call retains a separate stack. The stack is removed after the value from the proper function is returned.

Regarding resolving and tracking the values at each recursive call, recursion is reasonably tricky. Thus, You must keep track of the stack's contents and the variables' values. Examine the following example to learn more about how recursive functions allocate memory.

Now consider the following recursive Fibonacci algorithm for n = 5. All stacks are first saved before printing the matching value of n until n equals zero. The stacks are eliminated one at a time once the termination condition is met by returning 0 to the calling stack. Look at the diagram below to comprehend the call stack hierarchy.

Recursive Algorithm

C++

Output:

3 2 1 1 2 3 

Explanation

The above code prints from the given positive number to zero (0) and then again from zero (0) to the given number.

Time Complexity: O(1)

Auxiliary Space: O(1)

Java

Output:

3 2 1 1 2 3 

Explanation

The above code prints from the given positive number to zero (0) and then again from zero (0) to the given number.

Time Complexity: O(1)

Auxiliary Space: O(1)

Python

Output:

3 2 1 1 2 3 

Explanation

The above code prints from the given positive number to zero (0) and then again from zero (0) to the given number.

Time Complexity: O(1)

Auxiliary Space: O(1)

C#

Output:

3 2 1 1 2 3 

Explanation

The above code prints from the given positive number to zero (0) and then again from zero (0) to the given number.

Time Complexity: O(1)

Auxiliary Space: O(1)

PHP

Output:

3 2 1 1 2 3 

Explanation

The above code prints from the given positive number to zero (0) and then again from zero (0) to the given number.

Time Complexity: O(1)

Auxiliary Space: O(1)

Javascript

Output:

3 2 1 1 2 3 

Explanation

The above code prints from the given positive number to zero (0) and then again from zero (0) to the given number.

Time Complexity: O(1)

Auxiliary Space: O(1)

A local variable test is initialized to 3, and statements 1 through 4 are placed onto the stack when printing (3) is called from main(), as illustrated in the picture below. '3' is printed first. Statement 2 calls printFun(2), allocates memory for printFun(2), initializes the local variable test to 2, and pushes statements 1 through 4 onto the stack. PrintFun(0) calls printFun(1), and printFun(1) calls printFun(2) in a similar manner. After the if statement, printFun(0) returns to printFun(1). After completing printFun(1)'s remaining statements, it moves on to printFun(2) and so on. The values from 3 to 1 are written in the output first, followed by those from 1 to 3.

Recursive Algorithm

Recursion is a powerful method with several uses in programming and computer science. Here are a few of the typical uses for recursion:

  • Tree and graph traversal: When searching and traversing data structures like trees and graphs, recursion is widely utilized. Recursive algorithms can be used to systematically investigate each node or vertex of a tree or graph.
  • Sorting algorithms: Sorting algorithms like quicksort and merge sort also employ recursive algorithms. The data is split into smaller subarrays or sublists, sorted, and then combined using recursion in these techniques.
  • Divide-and-conquer algorithms: Many algorithms, like the binary search algorithm, employ a divide-and-conquer strategy using recursion to divide the more significant issue into smaller subproblems.
  • Fractal generation: Recursive algorithms may create fractal forms and patterns. For instance, the Mandelbrot set was created by continually applying complex numbers to a recursive algorithm.
  • Algorithms for backtracking Backtracking algorithms are employed to resolve issues involving a series of decisions, each dependent upon the prior decisions. Recursion can be used to create these algorithms to examine every avenue and go backward when a solution cannot be found.
  • Memorization: This strategy includes caching the outcomes of expensive function calls and returning them when identical inputs are provided again. Recursive functions can be used to compute and store the outcomes of subproblems to implement memory.

These are only a handful of the numerous uses for programming and computer science recursion. Recursion is a flexible and effective method that may address various issues.

Explanation: Here is an actual instance of recursion:

Programming recursion uses the idea of a function calling itself. It can effectively resolve challenging issues, but careful design is necessary to prevent infinite loops and stack overflows.

Here are the Implementations of Recursion Algorithm in different programming languages:

C++

Output:

120 

Explanation

The program mentioned above provides a function that outputs the factorial of a given number.

Java

Output:

120 

Explanation

The program mentioned above provides a function that outputs the factorial of a given number.

Python

Output:

120 

Explanation

The program mentioned above provides a function that outputs the factorial of a given number.

C#

Output:

120 

Explanation

The program mentioned above provides a function that outputs the factorial of a given number.

Javascript

Output:

120 

Explanation

The program mentioned above provides a function that outputs the factorial of a given number.

In this example, we define the factorial function, which accepts the number n as an argument. The factorial of n, or the product of all positive numbers up to n, is calculated by the function using recursion.

The primary cases for n are 0 and 1. Thus, the factorial function tests them first. Since 0! and 1! are 1, the method returns 1 if n is 0 or 1.

The function enters the recursive case if n is higher than 1. It makes a call to itself with the input n-1 and multiplies the outcome by n. This calculates n! by iteratively calculating (n-1)!

It's crucial to remember that recursion, if not handled appropriately, can be wasteful and result in stack overflows. The call stack grows by one frame with each function call; therefore, the stack may become manageable if the recursion is too deep. Recursion can also make it more challenging to comprehend and debug the code since it requires considering many function-call layers.

Recursion may also be an effective method for handling complicated issues, particularly when subdividing a more significant issue into smaller ones. Recursion may improve the code's elegance and readability when appropriately utilized.

What drawbacks exist between recursive and iterative programming?

Note that every recursive program can be constructed iteratively and vice versa. This means that both recursive and iterative programs have the same problem-solving capabilities. As all functions will stay on the stack until the base case is reached, the recursive program requires more storage space than the iterative program. Because of function calls and return overhead, it also takes more time.

Additionally, because the codes are shorter, they are harder to grasp, necessitating greater caution while creating them. The machine might run out of memory if the recursive calls are not adequately verified.

What benefits do recursive programming techniques have over iterative programming?

Recursion offers a neat and straightforward technique to construct code. Some issues, like tree traversals, the Tower of Hanoi, etc., are essentially recursive. Recursive coding is recommended for solving such issues. Such programs can also be created repeatedly with a stack data structure. The Iterative Tower of Hanoi and Inorder Tree Traversal without Recursion are examples.

Recursion is characterized by two situations: recursive cases and base cases.

  • When the case is valid, the base case ends the recursive function.
  • The method is duplicated on the stack memory with each recursive call.
  • If infinite recursion is used, stack memory may eventually run out.
  • Merge sort, Quick sort, Tower of Hanoi, Fibonacci Series, Factorial Problem, etc. are a few examples of recursive algorithms.

Conclusion

You learned what a recursive algorithm in programming is from this tutorial on recursive algorithms. You then learned about several recursion types and associated function call structures. You also examined how the sum of n natural numbers is implemented in programming. Finally, you also comprehended how a recursive procedure would be allocated memory inside the memory stack.

Simplilearn's Post Graduate Programme in Full Stack Web Development will be appropriate for you if you're seeking more in-depth instruction beyond data structures and covers the fundamentals of developing interactive applications. This internationally acclaimed program, provided in partnership with Caltech CTME, is intended to increase your chances of becoming a software developer by helping you become an expert in the field. So start your exploration now!







Youtube For Videos Join Our Youtube Channel: Join Now

Feedback


Help Others, Please Share

facebook twitter pinterest

Learn Latest Tutorials


Preparation


Trending Technologies


B.Tech / MCA