0% found this document useful (0 votes)
47 views19 pages

Final DSA GROUP 1

The document is an assignment on data structures and algorithms focused on recursion, detailing its definition, properties, and applications in programming. It discusses recursive functions, their implementation, advantages, and disadvantages, as well as comparing recursion with iteration. The content also includes examples of common recursive algorithms and real-world applications, emphasizing the importance of understanding recursion in computer science.

Uploaded by

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

Final DSA GROUP 1

The document is an assignment on data structures and algorithms focused on recursion, detailing its definition, properties, and applications in programming. It discusses recursive functions, their implementation, advantages, and disadvantages, as well as comparing recursion with iteration. The content also includes examples of common recursive algorithms and real-world applications, emphasizing the importance of understanding recursion in computer science.

Uploaded by

tegenefikadu91
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 19

MZAN- TEPI UNIVERSITY

COLLEGE OF ENGINEERING AND TECHNOLOGY

SCHOOL OF COMPUTING AND INFORMATICS

DEPARTEMENT OF: SOFTWARE ENGINEERING

ASSIGNMENT OF DATA STRUCTURE AND ALGORITHM

COURSE CODE: SEng 2022


GROUP 1 MEMBER

NAME ID

1. TEGENE FIKADU 6115/16

2. KALKIDAN AGUNE 4358/16

3. NESIREDIN JEMAL 4503/16

4. GATWECH KOANG 4284/16

SUBMITED TO Mr.WUBIE .A
SUBMITED DATE 22/07/2017 E.C
Table of content
Content page
Introduction.................................................................................................................................................1

1. What is Recursion in Data Structures?.....................................................................................................2

1.1. Recursive Function........................................................................................................................2

1.2. How Does Recursion Work in Programming?................................................................................3

1.3. Properties of Recursion.................................................................................................................5

2. Function Calls and Recursive Implementation.........................................................................................6

2.1. What Are Common Uses of Recursion in Data Structures?...........................................................8

2.2. Common Recursive Algorithms in Data Structures........................................................................9

2.3. Real-World Applications of Recursion...........................................................................................9

2.4. How to Analyze Recursion Performance?...................................................................................11

2.5. How to Implement Recursion in Data Structures?......................................................................12

2.6. Advantages of Recursion.............................................................................................................12

2.7. Disadvantages of Recursion........................................................................................................13

Conclusion.................................................................................................................................................14

Reference...................................................................................................................................................15

I
Introduction
Recursion is a programming wonder where a function invokes itself to solve complex
issues by dividing them into smaller, self-similar sub problems. Visualize it as a set of
nested Russian dolls: every layer brings you a simpler version of the problem until
you reach a base case — a stopping condition that prevents the infinite loop risk.

And this tactics performs well in data construction and helps provide a concise
solution for hierarchical tasks such as tree traversals (preorder,inorder,postorder),
graph algorithms like DFS, and sorting algorithms like Quicksort. Based on the Last-
In-First-Out (LIFO) stack type structure that it contains, recursion suspends each
function call into an activation record that contains parameters, variables, and a return
address.

But its beauty is not without a caveat: deep recursion can lead to stack overflow, and
iterative solutions often beat it in terms of memory use. But recursion’s concision and
fit with problem-solving intuition make it essential. How does a function recursively
calling itself transform maze-like difficulties into step-by-step-solvable problems?
Let’s unravel the art of recursion.

1
1. What is Recursion in Data Structures?
Recursion is the process in which a function calls itself again and again. It entails
decomposing a challenging issue into more manageable issues and then solving each one
again. There must be a terminating condition to stop such recursive calls. Recursion may
also be called the alternative to iteration. Recursion provides us with an elegant way to
solve complex problems, by breaking them down into smaller problems and with fewer
lines of code than iteration.

Think of it as peeling layers of an onion—each layer reveals a simpler problem inside.


When you ask, "What is recursion in data structure?" picture standing between two
mirrors, reflecting endlessly. Recursion creates a chain of calls, each similar to the last,
but it doesn't go on forever. A base case stops the process, preventing an infinite loop.

1.1. Recursive Function


A recursive function is a function that calls itself one or more times within its body. A
recursive function solves a particular problem by calling a copy of itself and solving
smaller sub problems of the original problems. Many more recursive calls can be
generated as and when required.
It is necessary to have a terminating condition or a base case in recursion; otherwise,
these calls may go endlessly leading to an infinite loop of recursive calls and call stack
overflow.
The recursive function uses the LIFO (LAST IN FIRST OUT) structure just like the stack
data structure. A recursion tree is a diagram of the function calls connected by pointed (up
or down) arrows to depict the order in which the calls were made.

2
Syntax to Declare a Recursive Function

recursion_ function(){

recursion_function() // calling self function

1.2. How Does Recursion Work in Programming?


Recursion in data structure solves problems by repeating a process in a self-referential
way. Think of it as peeling layers of an onion—each step reveals a smaller piece of the
problem until there’s nothing left to peel. This method relies on two key elements: a base
case to stop the process and a recursive case to continue solving.

The base case is the heart of recursion. It sets the condition for stopping. Without it, your
program will hit a "stack overflow," crashing like a house of cards in a storm. The
recursive case, on the other hand, is what drives the function to keep calling itself.
Together, these two create the rhythm of recursion in data structure.

3
For example, calculating the factorial

#include<iostream>

using namespace std;

int factorial(int n){

If(n==0 || n==1){

return 1;

else{

return n* factorial(n-1); //calling self function

int main(){

int num;

cout<<”Enter Non negative Integer”;

cin>>num;

cout<<”Factorial of “<<num<<”is”<<factorial(num);

return 0;

4
Each recursive call reduces the problem’s size, making recursion a highly efficient
approach.

Figure 1

1.3. Properties of Recursion


1. It solves a problem by breaking it down into smaller sub-problems, each of which
can be solved in the same way.

2. A recursive function must have a base case or stopping criteria to avoid infinite
recursion.

3. Recursion involves calling the same function within itself, which leads to a call
stack.

4. Recursive functions may be less efficient than iterative solutions in terms of


memory and performance.

5
2. Function Calls and Recursive Implementation
 What kind of information must we keep track of when a function is called?
 If the function has parameters, they need to be initialized to their corresponding
arguments.
 In addition, we need to know where to resume the calling function once the called
function is complete.
 Since functions can be called from other functions, we also need to keep track of
local variables for scope purposes.
 Because we may not know in advance how many calls will occur, a stack is a
more efficient location to save information.
 So we can characterize the state of a function by a set of information, called an
activation record or stack frame.
 This is stored on the runtime stack, and contains the following information:
 Values of the function’s parameters, addresses of reference variables (including
arrays) – Copies of local variables.
 The return address of the calling function.
 A dynamic link to the calling function’s activation record.
 The function’s return value if it is not void.
 Every time a function is called, its activation record is created and placed on the
runtime stack.
 So the runtime stack always contains the current state of the function.
 As an illustration, consider a function f1()called from main()
 It in turn calls function f2 (), which calls function f3 ().
 The current state of the stack, with function f3()executing, is shown in Figure 1.2
 Once f3 () completes, its record is popped, and function f2 () can resume and
access information in its record.
6
 If f3 () calls another function, the new function has its activation record pushed
onto the stack as f3 () is suspended.

Figure 2

Contents of the run time stack when main () call function f1(), f1() call f2() and f2() call
f3().

The use of activation records on the runtime stack allows recursion to be implemented
and handled correctly.

 Essentially, when a function calls itself recursively, it pushes a new activation


record of itself on the stack.
 This suspends the calling instance of the function, and allows the new activation to
carry on the process.

7
 Thus, a recursive call creates a series of activation records for different instances
of the same function.

2.1. What Are Common Uses of Recursion in Data Structures?


Recursion in data structure powers some of the most critical operations in programming.
It provides solutions for problems that are inherently hierarchical or repetitive. By
leveraging recursion, you can tackle complex tasks with simplicity and precision,
unlocking the potential of many algorithms and methods.

The applications mentioned below highlight the powerful capabilities of recursion in


data structures.

 Tree Traversal Methods: Recursion simplifies traversing tree structures in


various orders such as pre-order, in-order, and post-order. These methods allow
you to explore hierarchical data, from folder directories to XML documents,
without breaking a sweat.
 Graph Algorithms: Depth-first search (DFS), a classic example of recursion in
data structure, dives deep into a graph to explore its nodes efficiently. It mimics
human curiosity, exploring paths before backtracking, making it ideal for puzzles
or solving mazes.
 Dynamic Programming: Recursive solutions are foundational in dynamic
programming, where overlapping sub problems are solved efficiently. Think
Fibonacci series or optimal ways to climb stairs—it’s all about breaking problems
into manageable parts.
 Backtracking: Recursive backtracking shines in scenarios like Sudoku solving,
N-Queens problems, or word searches. It tries every possibility, retreats when it
hits a dead end, and continues until a solution is found.
8
 Divide and Conquer: Algorithms like Merge Sort and Quick Sort rely on
recursion to split problems into smaller chunks. Recursion makes these tasks as
straightforward as slicing a pizza into manageable portions.

2.2. Common Recursive Algorithms in Data Structures


Recursion in data structures simplifies complex tasks by dividing them into smaller,
manageable parts. From binary trees to sorting, it provides precise solutions for
hierarchical and sequential problems. These examples showcase how recursion in data
structures powers key algorithms.

 Binary Tree Traversals (Inorder, Preorder, Postorder): Recursive methods


traverse nodes systematically. For example, in-order traversal visits the left
subtree, the root, and then the right subtree.
 Graph Algorithms (DFS, BFS): Depth-first search (DFS) relies on recursion to
explore nodes deeply before backtracking. While BFS uses iteration, recursive
DFS efficiently uncovers all paths.
 Sorting Algorithms (Quicksort, Mergesort): Quicksort uses recursion to

partition elements around a pivot. Merge sort divides arrays recursively, merges
sorted halves, and creates order from chaos.

2.3. Real-World Applications of Recursion.


Recursion in data structures extends its power beyond algorithms, shaping solutions for
everyday computational challenges. Its elegance translates into solving problems from
navigating file systems to building artificial intelligence solutions. Mentioned below are
some fascinating real-world applications where recursion takes center stage.

9
 File System Navigation: Recursion effortlessly explores nested directories,
mimicking the structure of a tree. It processes files layer by layer, making
organization manageable.
 Web Crawling: Crawlers use recursion to traverse web pages. They fetch links
from a page, follow each one recursively, and build comprehensive datasets.
 AI and Puzzles: Recursive backtracking powers puzzles like Sudoku, the N-
Queens problem, and game strategies in AI. It evaluates every possible move to
identify the winning solution. Recursion seamlessly blends theory with practice,
making it a cornerstone of efficient programming. But how does it compare to
iteration?

2.4. Recursion vs. Iteration: Which Is Better?

When solving problems, you often face a choice between recursion and iteration. Both
have their strengths, but they suit different scenarios. Recursion in data structure relies on
breaking problems into smaller tasks, while iteration processes them step by step in
loops.

Aspect Recursion Iteration

Use Case Ideal for problems with Best for repetitive tasks
hierarchical or tree-like without hierarchy (e.g., loops).
structures (e.g., DFS, tree
traversals).

Performance Can be slower due to function Faster as it avoids stack


call overhead management overhead.

Complexity Code is concise but harder to Code is longer but easier to


debug. follow

10
Scalability Limited by stack size; prone to Easily handles larger data sets
stack overflow in deep without stack limitations.
recursion.

2.4. How to Analyze Recursion Performance?


Analyzing recursion in data structures involves evaluating its time and space complexity.
Recursive functions can quickly become inefficient without proper consideration of their
computational demands. Understanding the call stack, base case execution, and
optimizations like tail recursion helps you assess their performance and refine your code.
The key aspects you need to evaluate when analyzing recursive functions are mentioned
below.

 Time Complexity: Analyze how many times the function calls itself. For
example, recursion in divide-and-conquer algorithms often has a time complexity
of O(n log n).
 Space Complexity: Consider the memory consumed by the call stack. Each
recursive call adds a new stack frame, which can cause stack overflow in deep
recursion.
 Call Stack Behavior: Examine the depth of recursion. Tail recursion minimizes
stack usage, while non-tail recursion adds frames for intermediate computations.
 Base Case Efficiency: A well-designed base case stops unnecessary calls.
Inefficient base cases lead to wasted computations.

11
 Optimizations like Tail Recursion: Tail recursion reduces memory usage by
allowing the compiler to optimize recursive calls, reusing stack frames instead of
creating new ones.

2.5. How to Implement Recursion in Data Structures?


Implementing recursion in data structures requires a systematic approach. It involves
understanding the problem, designing the base case, and ensuring the recursive logic
works seamlessly. You need to think like a problem-solver, breaking down the task into
smaller parts while ensuring the logic flows back to the solution. Below is the step-by-
step process to help you implement recursive methods effectively:

 Understand the Problem: Identify the task's hierarchical or repetitive nature. For
example, navigating a tree or performing a factorial calculation.
 Define the Base Case: Set a stopping condition to prevent infinite recursion.
Ensure this case handles the smallest instance of the problem.
 Break down the Problem: Divide the task into smaller, manageable parts. Each
recursive call should reduce the problem size or complexity.
 Write the Recursive Case: Implement the logic where the function calls itself.
Make sure it aligns with the base case to avoid errors.
 Test for Edge Cases: Check scenarios like zero inputs, negative numbers, or large
datasets. Ensure your function handles all cases gracefully.

12
 Analyze and Optimize: Review the function’s time and space complexity. Use
tail recursion or other techniques to improve efficiency.

2.6. Advantages of Recursion


1. Clarity and simplicity: Recursion can make code more readable and easier to
understand. Recursive functions can be easier to read than iterative functions when
solving certain types of problems, such as those that involve tree or graph
structures.

2. Reducing code duplication: Recursive functions can help reduce code


duplication by allowing a function to be defined once and called multiple times
with different parameters.

3. Solving complex problems: Recursion can be a powerful technique for solving


complex problems, particularly those that involve dividing a problem into smaller
sub problems.

4. Flexibility: Recursive functions can be more flexible than iterative functions


because they can handle inputs of varying sizes without needing to know the exact
number of iterations required.

2.7. Disadvantages of Recursion

1. Performance Overhead: Recursive algorithms may have a higher performance


overhead compared to iterative solutions. This is because each recursive call
creates a new stack frame, which takes up additional memory and CPU resources.
Recursion may also cause stack overflow errors if the recursion depth becomes too
deep.
13
2. Difficult to understand and Debug: Recursive algorithms can be difficult to
understand and debug because they rely on multiple function calls, which can
make the code more complex and harder to follow.

3. Memory Consumption: Recursive algorithms may consume a large amount of


memory if the recursion depth is very deep.

4. Limited Scalability: Recursive algorithms may not scale well for very large input
sizes because the recursion depth can become too deep and lead to performance
and memory issues.

5. Tail Recursion Optimization: In some programming languages, tail recursion


optimization is not supported, which means that tail recursive functions can be
slow and may cause stack overflow errors.

Conclusion
Standing out as a clean, elegant paradigm in computer science is a concept called recursion,
the concept of breaking down complex problems into simpler, self-referential ones that
mirror the structure of the original problem. For hierarchical problems such as tree traversals
(in-order, pre-order, post-order), graph navigations (DFS), and sort algorithms (Quicksort,
Merge Sort), by utilizing recursion a programmer could create solutions that are both very
intuitive and concise. Its capacity to replicate human intuitively in addressing problems,
much like removing an onion layer or conquering.

Directories—make it essential for cases requiring stepwise refinement. But the beauty of
recursion is coupled with practical limitations: deep recursion can lead to stack overflow, and
the overhead in memory usage intrinsic to its runtime semantics usually makes iterative
processes more efficient for large-scale computations. The secret behind recursion is its

14
proper utilization: clearly formulated base cases, where possible, recursions without
depreciation, and the consistent balance between literary style and performance.

Though recursion has many applications like dynamic programming, backtracking, divide-
and-conquer, one should always consider the tradeoffs between elegance and efficiency
while using it. In the end, recursion is a double-edged sword that follows the pattern of most
computer science concepts in that it can offer incredibly elegant solutions to problems
provided it is used with care and an understanding of its limitations.

15
Reference
A. Drozdek, Data Structures and Algorithms in C++ (2nd ed.). Cengage Learning, 2013. Boston,
MA, USA.

Cormen, T.H., Leiserson, C.E., Rivest, R.L., & Stein, C. (2009). Introduction to Algorithms (3rd
ed. ed.). MIT Press.

Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley Professional.

Tanenbaum A. S. Augenstein M. J. (1986). Data Structures Using C. Upper Saddle River, New
Jersey: Prentice Hall.

Aho, A. V., Lam, M. S., Sethi, R., & Ullman, J. D. (2006). Compilers Principles Techniques And
Tools

16

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy