0% found this document useful (0 votes)
13 views53 pages

Hemanth Summer Internship

The document is a training report submitted by Hemanth Chowdary Sunkavalli for a summer internship at Lovely Professional University, focusing on mastering data structures and algorithms. It outlines the objectives, scope, importance, and learning outcomes of the internship, along with a detailed description of the work done, challenges faced, and skills acquired. The report emphasizes the significance of data structures and algorithms in programming and their applications in solving real-world problems.
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)
13 views53 pages

Hemanth Summer Internship

The document is a training report submitted by Hemanth Chowdary Sunkavalli for a summer internship at Lovely Professional University, focusing on mastering data structures and algorithms. It outlines the objectives, scope, importance, and learning outcomes of the internship, along with a detailed description of the work done, challenges faced, and skills acquired. The report emphasizes the significance of data structures and algorithms in programming and their applications in solving real-world problems.
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/ 53

Annexure-I

Summer Internship

Lovely Professional University

A training report

Submitted in partial fulfilment of the requirements for the award of degree of

Bachelor of Technology in Computer Science and Engineering

Submitted to

LOVELY PROFESSIONAL UNIVERSITY

PHAGWARA, PUNJAB

From 06/05/24 to 07/17/24

SUBMITTED BY

Name of student: Hemanth Chowdary Sunkavalli


Registration Number: 12209061
Signature of the student: Hemanth

1|Page
Annexure-II: Student Declaration

To whom so ever it may concern


I, Hemanth Chowdary, 12209061, hereby declare that the work done by me on
“Mastering Data Structures and Algorithms:Theory to Practice from June, 2024 to
July, 2024, is a record of original work for the partial fulfillment of the requirements for
the award of the degree, Bachelor of Technology in Computer Science and
Engineering.

Hemanth Chowdary (12209061)

Signature of the student: Hemanth

Dated: 25-08-2024

2|Page
ACKNOWLEDGEMENT

Primarily I would like to thank God for being able to learn a new technology. Then I
would like to express my special thanks of gratitude to the teacher and instructor of the
course Mastering Data Structures : Theory to practice who provide me the golden
opportunity to learn a new technology from home.

I would like to also thank my own college Lovely Professional University for offering
such a course which not only improve my programming skill but also taught me other
new technology.

Then I would like to thank my parents and friends who have helped me with their
valuable suggestions and guidance for choosing this course.

Last but not the least I would like to thank my all classmates who have helped me a lot.

[Hemanth Chowdary]
[12209061]

3|Page
 INTERNSHIP CERTIFICATE

4|Page
TABLE OF CONTENTS

S.NO TITLE PAGE

1 COVER PAGE 1

2 DECLARATION OF THE STUDENT 2

3 ACKNOWLEDGEMENT 3

4 TRAINING CERTICATE FROM ORGANISATION 4

5 INTRODUCTION 6-8

6 BREIF DESCRIPTION OF THE WORK DONE 9-10

7 THE CONTENT 11 - 47

8 THE PROJECT

9 CONCLUSION

10 BIBLIOGRAPHY 52

5|Page
INTRODUCTION OF THE PROJECT UNDERTAKEN

 Objectives of the work undertaken

1. Understanding Core Data Structures: Develop a deep understanding of


fundamental data structures such as arrays, linked lists, stacks, queues, trees, heaps,
hash tables, graphs, etc.

2. Hands-on Implementation: Gain practical experience by implementing these data


structures in programming languages like C++, Java, or Python.

3. Optimization Techniques: Learn optimization techniques for memory management


and efficient algorithms to solve computational problems using data structures.

 Scope of work

1. Theoretical Understanding: The scope covers in-depth analysis of data structures


and their operations, including complexity analysis (time and space).

2. Algorithm Design: Designing and understanding algorithms that effectively utilize


these data structures for sorting, searching, and data manipulation.

6|Page
 Importance and Applicabilities

1. Performance Optimization:

 Data structures and algorithms are the backbone of high-performance systems. By


choosing the right data structure and algorithm, developers can significantly
reduce the time complexity and memory usage of their programs, leading to faster
execution times and reduced resource consumption.

2. Efficient Problem Solving:

 Understanding different data structures (like arrays, trees, and graphs) and
algorithms (like sorting, searching, and dynamic programming) allows developers
to approach problems in a structured manner. For instance, using a graph traversal
algorithm can solve network-related problems more efficiently than brute-force
methods.
3. Memory Efficiency:

 Proper use of data structures helps in optimizing memory usage. For example, a
hash table may be used for constant-time lookups, while a tree-based structure can
be used when ordering is important. This helps in conserving memory, especially
in memory-constrained environments like embedded systems or mobile
applications.

4. Adaptability and Scalability:

 Programs that implement efficient data structures and algorithms can scale to
handle larger datasets or more complex operations. As the volume of data
increases (e.g., in big data applications), selecting the right algorithms ensures
that the system remains responsive and efficient.

5. Real-World Problem Solving:


 Many real-world problems can be modeled using data structures. For example, a
navigation app might use graph algorithms for finding the shortest path between
two points, or a social media platform might employ trees and heaps for
organizing and displaying user feeds.

7|Page
 Role and profile

Role: Data Structures Intern / Algorithm Intern

• Worked on mastering and implementing various data structures and algorithms.

• Focused on both theoretical understanding and practical application of data


structures in solving complex computational problems.

• Assisted in the development and testing of projects where data structures played a key
role.

Profile:

 Skills: Proficient in programming languages (C++, Java, Python), strong


understanding of data structures (arrays, trees, graphs, etc.), problem-solving,
and algorithm design.

 Responsibilities: Implemented data structures, optimized existing codebases,


contributed to project development, and participated in problem-solving
discussions.

 Outcome: Strengthened coding skills, enhanced knowledge of data structures,


and applied these skills to real-world scenarios, preparing for advanced roles in
software development or related fields.

8|Page
BRIEF DESCRITION OF WORKDONE

Code Review and Quality Assurance:

Position of Internship and role


• Participated in peer code reviews, ensuring code quality, adherence to best practices,
and identifying potential bugs or inefficiencies in the implementation of data structures.
Documentation and Knowledge Sharing: • Documented the implementation details,
challenges, and performance benchmarks of different data structures. Created knowledge-
sharing presentations or guides for team members on best practices in algorithm design
and data structure usage.

 Activities/ equipment handled

1. Online Coding Platforms:


• Worked on coding platforms like LeetCode, HackerRank, Codeforces, or
GeeksforGeeks to solve data structure and algorithm problems. Participated in coding
challenges to test and refine your skills.

2. Text Editors:
• Used simple text editors such as Notepad++ or Sublime Text for writing and organizing
code snippets during the implementation of data structures.

 Challenges faced and how those were tackled

1. Optimizing Performance: Struggled to achieve the desired performance for certain


data structures when handling large datasets. Overcame this by conducting in-depth
complexity analysis and refactoring code, replacing inefficient algorithms with better
alternatives.

2. Debugging Complex Code: Encountered difficulties in debugging large, complex


codebases, particularly with graph and tree structures. Solved this by breaking down the
problem into smaller components, using step-by-step debugging and adding extensive
logging.

3. Debugging Complex Code: Encountered difficulties in debugging large, complex code


base particularly with graph and tree structures. Solved this by breaking down the problem
into smaller components, using step-by-step debugging and adding extensive logging.
9|Page
 Learning outcomes

1. Deep Understanding of Data Structures: Gained a thorough knowledge of various


data
• structures and their applications in solving real-world problems.

2. Problem-Solving Skills: Improved problem-solving skills, specifically in the areas of


algorithmic thinking and performance optimization.

3. Coding Proficiency: Enhanced proficiency in coding, particularly in languages like


C++, Java, and Python, with an emphasis on clean and modular code.

 Data analysis

• Performance Metrics: Collected and analyzed performance data on implemented data


structures, including execution time, memory usage, and scalability.

• Complexity Analysis: Conducted theoretical and practical analysis of time and space
complexity for each data structure implemented.

• Visualization: Used visualization tools to represent data structures graphically,


analysing their behaviour in different states (e.g., insertion, deletion, searching).

10 | P a g e
INTRODUCTION TO DATA STRUCTURES AND ALGORITHMS:

 OVERVIEW OF DATA STRUCTURES AND ALGORITHMS:

DataStructures:
Data structures are ways of organizing and storing data in a
computer so that it can be accessed and modified efficiently. They
provide a framework for managing large amounts of data, enabling
the efficient performance of various operations like insertion,
deletion, and search. Common data structures include arrays, linked
lists, stacks, queues, trees, graphs, and hash tables.

Algorithms:
An algorithm is a step-by-step procedure or a set of rules followed
in calculations or other problem-solving operations. Algorithms
take inputs, process them through various data structures, and
produce desired outputs. Some well-known algorithms include
sorting (e.g., quicksort, mergesort), searching (e.g., binary search),
and graph traversal (e.g., depth-first search).
Together, data structures and algorithms form the foundation of
computer science and programming, facilitating efficient data
management and problem-solving.

11 | P a g e
 Importance of Data Structures and Algorithms in
Programming

Data structures and algorithms are critical in programming for


several reasons:
1. Efficiency: They enable programs to run efficiently by
optimizing how data is stored and processed. For example,
using a hash table instead of a list for lookups can significantly
reduce the time complexity.

2. Scalability: Algorithms and data structures allow programs to


handle large datasets without performance degradation.
Properly designed systems can scale as data grows.

3. Optimization: Many real-world problems require solutions that


can handle millions of operations per second. Optimized
algorithms can perform tasks quickly and use minimal
resources.

4. Problem Solving: Knowledge of data structures and algorithms


enables programmers to choose the best approach for solving
complex problems and enhances critical thinking.

5. Technical Interviews: Understanding and applying data


structures and algorithms are essential for technical interviews
in most software development jobs, as they are a key indicator
of problem-solving abilities and coding skills.

 Basic Concepts of Time Complexity and Space Complexity:

Time Complexity:
Time complexity is a me assure of the amount of time an algorithm
takes to complete as a function of the size of the input. It helps
predict how an algorithm's execution time increases with the input
size. For example, a linear time complexity (O(n)) means that if the
input size doubles, the time required will also double. Common
time complexities include O(1) (constant time), O(n) (linear time),
O(n²) (quadratic time), and O(log n) (logarithmic time).

Space Complexity:
Space complexity refers to the amount of memory or space an
algorithm requires relative to the size of the input data. It accounts
for all the memory used, including the input data, auxiliary space
for variables, and function calls. Efficient algorithms should
optimize space usage, especially in memory-constrained
environments.

12 | P a g e
Both time and space complexity are critical in determining the
performance of algorithms, ensuring that programs run quickly and
efficiently even with large datasets.

 Introduction to Big O (O), Omega (Ω), and Theta (Θ)


Notation:

Big O (O)Notation:
Big O notation is used to describe the worst-case time or space
complexity of an algorithm, providing an upper bound on the
algorithm’s growth rate. It tells us the maximum amount of time or
space that the algorithm will require, regardless of the input size.
For example, O(n) means the time required grows linearly with the
input size, while O(1) means the time required is constant, no
matter the input size.

Omega (Ω)Notation:
Omega notation provides the lower bound for the time complexity
of an algorithm. It describes the best-case scenario or the minimum
time an algorithm will take to complete. For example, Ω(n) means
that, at the very least, the algorithm will take linear time.

Theta (Θ)Notation:
Theta notation provides a tight bound on the time complexity of an
algorithm. It means that the algorithm’s performance will always be
within a certain range, bounded both above and below. For
example, Θ(n) indicates that the algorithm will take linear time in
both the worst and best cases.
These notations help developers evaluate and compare the
efficiency of different algorithms, enabling informed decisions
about which algorithms to use based on the specific requirements
and constraints of a problem.

13 | P a g e
ARRAYS AND LINKED LISTS:

 Introduction to Arrays

An array is a data structure that stores a collection of elements (values or variables), each
identified by an array index or key. The elements are stored in contiguous memory
locations, and this direct, sequential storage enables fast and efficient access to any
element using its index.

 Basic Operations:

Access: Accessing any element in an array is a simple and constant time operation
(`O(1)`), because each element's position is calculated as an offset from the base address
of the array.
Insertion:

At the End: Inserting an element at the end of the array takes `O(1)` time if there's
sufficient space.

At the Beginning or Middle: Requires shifting elements, resulting in `O(n)` time


complexity where `n` is the number of elements.

Deletion:

At the End: Deletion of the last element takes constant time `O(1)`.
At the Beginning or Middle: Similar to insertion, deletion requires shifting elements
and takes `O(n)` time.

Search:
Linear Search: Searching for an element by scanning the array takes `O(n)`.
Binary Search: If the array is sorted, binary search can be used to find an element in
`O(log n)`.

14 | P a g e
 Advantages:

Fast Access: Because arrays use indexed access, reading or modifying an element is
extremely fast.

Predictable Memory Usage: Since the size of an array is fixed at the time of its
creation, memory allocation is predictable and efficient.

Cache Friendly: Due to the contiguous nature of arrays, they are cache-friendly and
can lead to better performance with respect to modern CPU architectures.

 Limitations:

Fixed Size: Arrays cannot change size once defined, leading to possible
wasted memory or insufficient space.

Costly Insertion/Deletion: Inserting or deleting an element in the middle of


the array requires shifting elements, which is inefficient.

Contiguous Memory Requirement: Arrays require a block of contiguous


memory, which can be problematic when dealing with large datasets in
systems with fragmented memory.

15 | P a g e
 Introduction to Linked Lists

A linked list is a linear data structure where each element is a separate object called a node.
Each node contains two fields: one for storing the data and the other for storing a reference
(or pointer) to the next node in the sequence. Unlike arrays, linked lists do not store elements
in contiguous memory locations, and their size can grow or shrink dynamically as elements
are added or removed.

 Types of Linked Lists:

1. Singly Linked List:


In this type of linked list, each node has a single pointer pointing to the next node. The
last node in the list points to `NULL`, indicating the end of the list.

16 | P a g e
2. Doubly Linked List:
Each node has two pointers: one pointing to the next node and one pointing to the
previous node. This allows traversal in both forward and backward directions.

3. Circular Linked List:


The last node of the list points back to the first node, forming a circular structure.
Circular linked lists can be singly or doubly linked.

 Basic Operations:

Insertion:
At the Head: Inserting a node at the beginning of the list is `O(1)` since it only involves
updating pointers.
At the Tail: Inserting at the tail can also be efficient if a tail pointer is maintained
(`O(1)`); otherwise, it requires traversal (`O(n)`).

In the Middle: Inserting into the middle involves traversing to the desired location
(`O(n)`) and updating pointers.

Deletion:
At the Head: Deleting the first node is `O(1)`.

In the Middle or End: Deleting nodes requires traversal to find the node to be deleted
(`O(n)`).

17 | P a g e
Traversal: Traversal of a linked list always takes `O(n)` time since elements cannot be
accessed directly by index.

 Advantages:
Dynamic Size: Linked lists can easily grow or shrink in size as needed. No need to pre-
allocate memory.

Efficient Insertions/Deletions: Insertions and deletions (especially at the head or tail)


are more efficient than in arrays since no shifting is required.

No Memory Contiguity Requirement: Linked lists can be spread across non-


contiguous memory locations, allowing better use of available memory.

 Limitations:

Sequential Access: Accessing an element requires traversing the list from the head,
leading to `O(n)` time complexity.

Memory Overhead: Every node requires additional memory for storing a pointer to
the next node (or previous in doubly linked lists).

Increased Complexity: Manipulating pointers requires careful handling, making


linked lists more error-prone and complex to implement than arrays.

 Comparison Between Arrays and Linked Lists

 Size: Arrays have a fixed size determined at the time of declaration, while linked lists
can dynamically adjust their size.

 Access: Arrays provide constant-time O(1) access to elements via indexing, whereas
linked lists provide sequential access with O(n) complexity.

 Memory: Arrays require a block of contiguous memory, whereas linked lists allocate
memory dynamically and can operate on fragmented memory.

 Insertion/Deletion: Arrays have higher overhead for insertions/deletions as elements


need to be shifted. In contrast, linked lists allow for efficient insertions/deletions,
particularly at the beginning or end.

 Overhead: Linked lists require extra memory for pointers, while arrays have a lower
overhead since no pointers are required.

18 | P a g e
 Conclusion:

Arrays and linked lists each have their unique strengths and weaknesses, making them
suited to different types of problems. Arrays are ideal for scenarios where fast, random
access to elements is critical, and the size of the data is known ahead of time. In contrast,
linked lists excel in situations where frequent insertions and deletions are required, and
the data size may fluctuate unpredictably.

19 | P a g e
STACKS, QUEUES AND RECURSION:

 Introduction to Stacks

A stack is a linear data structure that follows the Last In, First Out (LIFO) principle. This
means the last element added is the first one to be removed.

 Operations:
 Push: Adds an element to the top of the stack.

 Pop: Removes the top element from the stack.

 Peek/Top: Returns the top element without removing it.

 isEmpty: Checks if the stack is empty.

 Implementation:

 Array-Based Stack: Uses a fixed-size array to store elements. Simple but limited by the
array's capacity.

 Linked List-Based Stack: Uses nodes with pointers to dynamically allocate memory.
This allows unlimited size but requires additional memory for pointers.

20 | P a g e
 Applications:

 Function Call Management: The call stack manages function calls in programming,
storing local variables and return addresses.

 Undo Mechanism: In text editors or games, stacks are used to implement undo
functionality.

 Expression Evaluation: In compilers, stacks help evaluate expressions and parse syntax
trees.

 Introduction to Queues:

A queue is a linear data structure that follows the First In, First Out (FIFO) principle,
meaning the first element added is the first one to be removed.

Operations:
 Enqueue: Adds an element to the end (rear) of the queue.

 Dequeue: Removes an element from the front of the queue.

 Front/Peek: Returns the front element without removing it.

 Is Empty: Checks if the queue is empty.

Implementation:
21 | P a g e
 Array-Based Queue: Can be implemented using a circular array to avoid shifting
elements.

 Linked List-Based Queue: Uses nodes for dynamic memory allocation, avoiding size
limitations.

Applications:
 CPU Scheduling: Queues manage processes in operating systems.

 Print Spooling: Printers use queues to manage print jobs.

 Breadth-First Search (BFS): Queues are fundamental to the BFS algorithm used in
graph traversal.

 Introduction to Recursion:

Recursion is a technique where a function calls itself to solve a problem. Recursive solutions
often break the problem down into smaller, similar subproblems until reaching a base case that
can be solved directly.

Basic Concepts:
 Base Case: The condition that stops the recursion. Without a base case, recursion would
result in infinite calls.

22 | P a g e
 Recursive Case: The part of the function where it calls itself to work on a smaller or
simpler instance of the problem.

Examples:
 Factorial: n! = n * (n-1)!, where factorial(0) = 1 is the base case.

 Fibonacci Sequence: F(n) = F(n-1) + F(n-2), with base cases F(0) = 0 and F(1) = 1.

4. Recursion vs. Iteration:


Both recursion and iteration (loops) are ways to repeat a process. However, they differ in their
approach:

Recursion:
 Concept: Solves a problem by breaking it down into smaller instances of the same
problem, requiring function calls.

 Memory Usage: Requires more memory due to the function call stack.

 Code Structure: Generally more elegant and concise for certain problems like tree
traversals.

Iteration:
 Concept: Repeats a process by looping through the elements until a condition is met.

 Memory Usage: More efficient in memory usage since no additional function calls are
required.

 Code Structure: Can be more complex for problems that are naturally recursive, like
backtracking or divide and conquer.

Example: Factorial Calculation:


Recursive:

def factorial(n):

if n == 0:

return 1

else:

23 | P a g e
return n * factorial(n - 1)

Iterative:

def factorial(n):

result = 1

for i in range(1, n + 1):

result *= i

return result

 Conclusion:

Stacks and queues are fundamental data structures used in various real-world applications, from
CPU scheduling to managing undo operations. Recursion, a powerful tool for solving problems,
often provides a simpler approach compared to iteration but comes with the trade-off of higher
memory usage due to the call stack. Understanding these concepts is critical for tackling
complex programming challenges.

24 | P a g e
 TREES AND BALANCED TREES:

 Introduction to Trees:

A tree is a non-linear data structure used to represent hierarchical relationships between


elements. It consists of nodes connected by edges. Trees are widely used in computer
science for tasks like representing hierarchical data (such as file systems) or for efficient
searching and sorting algorithms.

 Basic Terminology and Properties:

 Node: The fundamental unit of a tree that contains data and may link to other nodes
(children).
 Root: The topmost node of the tree, which has no parent.
 Parent: A node that has one or more children.
 Child: A node that is directly connected to another node when moving away from the
root.
 Sibling: Nodes that share the same parent.
 Leaf Node: A node that has no children; it is the endpoint of a path in the tree.
 Internal Node: A node with at least one child.
 Subtree: A portion of the tree that itself is a tree, consisting of a node and all of its
descendants.
 Height: The length of the longest path from the root to a leaf.
 Depth: The distance from the root to a particular node.
 Level: All nodes at the same depth are said to be on the same level.
Properties:
 Acyclic: Trees contain no cycles (loops).
 Connected: There is exactly one path between any two nodes.
 Hierarchy: Trees naturally represent hierarchical structures where one element leads to
one or more dependent elements.

25 | P a g e
 Binary Trees:

A binary tree is a special type of tree in which each node has at most two children,
typically referred to as the left and right child.

Properties:

 Complete Binary Tree: All levels are fully filled except possibly the last level, which is
filled from left to right.

 Full Binary Tree: Every node has 0 or 2 children, i.e., no nodes have only one child.

 Perfect Binary Tree: A full binary tree where all leaf nodes are at the same level, and
every level is fully filled.
 Balanced Binary Tree: A binary tree where the height of the two child subtrees of any
node difference by not more than one.

 Basic Operations:

1. Insertion: Adding a node to a binary tree involves finding the appropriate position based
on a specific criterion (e.g., level-order for completeness).
2. Deletion:

26 | P a g e
 Leaf Deletion: Simply remove the node.
 One Child Deletion: Replace the node with its child.
 Two Children Deletion: Replace the node with its in-order successor or
predecessor.
3. Traversal:
 In order (LNR): Visit left subtree, node, then right subtree.
 Preorder (NLR): Visit node, then left subtree, then right subtree.
 Post order (LRN): Visit left subtree, then right subtree, then node.
 Level-order: Traverse the tree level by level from top to bottom.

 Binary Search Trees (BSTs):

A binary search tree (BST) is a binary tree where nodes are arranged in a specific order:
for each node, all elements in the left subtree are smaller, and all elements in the right
subtree are larger.

 Properties:

27 | P a g e
 Sorted Structure: This property allows efficient searching, insertion, and deletion
operations.
 Uniqueness: Typically, no two nodes have the same value (to maintain the binary search
property).
 Dynamic: Can grow and shrink as elements are added or removed.

 Basic Operations:
1. Search:
 Efficiently finds a node by comparing values. The time complexity is O(log n) in
a balanced tree but can degrade to O(n) in an unbalanced tree.
2. Insertion:
 Inserting a new node involves traversing the tree until the correct position is
found that maintains the binary search property.
3. Deletion:
 Leaf Node: Simply remove the node.
 Node with One Child: Replace the node with its child.
 Node with Two Children: Replace with its in-order successor (the smallest node
in the right subtree) or in-order predecessor (the largest node in the left subtree).

 Advantages:

 Efficient Search: Provides faster search times than unsorted structures like linked lists.
 Order: Maintains elements in a sorted order, making in-order traversal ideal for
producing sorted data.

 Limitations:
 Unbalanced Trees: When nodes are inserted in sorted order, BSTs can become skewed,
degrading performance to O(n).

28 | P a g e
 Balanced Binary Trees:

Balanced binary trees are binary trees that automatically adjust their structure to ensure
that operations like search, insertion, and deletion maintain a logarithmic time complexity
(O(log n)).

29 | P a g e
 Balanced Trees and AVL Trees:

An AVL tree is a self-balancing binary search tree where the heights of the left and right
subtrees of any node differ by no more than one. AVL trees are named after their
inventors, Adelson and Landis.

 Properties:

 Balance Factor: For any node, the height difference between the left and right subtree
should be at most ±1.
 Self-Balancing: After each insertion or deletion, the tree performs rotations to restore
balance.
 Time Complexity: Operations like search, insertion, and deletion are guaranteed to be O
(log n) in an AVL tree.
Rotations:
 Right Rotation: Performed when the tree becomes unbalanced due to heavy left subtree
(left-left case).
 Left Rotation: Performed when the tree becomes unbalanced due to heavy right subtree
(right-right case).
 Left-Right Rotation: Combination of left rotation followed by right rotation, used in
left-right imbalance.
 Right-Left Rotation: Combination of right rotation followed by left rotation, used in
right-left imbalance.
 Operations in AVL Trees:

Insertion:

 Insertions follow the same rules as a binary search tree. After inserting a node, if
the balance factor becomes out of range (±1), rotations are performed to restore
balance.

Deletion:

 Similar to insertion, after deleting a node, the tree checks the balance factors of all
affected nodes and performs rotations if needed.

30 | P a g e
Search:

 Searching in an AVL tree is efficient, with a time complexity of O(log n), as the
tree remains balanced.

 Advantages:

 Consistent Performance: Ensures that all basic operations maintain logarithmic time
complexity, even in the worst case.
 Sorted Structure: Like other binary search trees, AVL trees maintain sorted order,
making them useful for ordered data.

 Limitations:

 Higher Overhead: The balancing operations increase the complexity and runtime of
insertion and deletion operations slightly compared to unbalanced BSTs.
 More Complex Implementation: AVL trees are more complex to implement due to the
need for rotations and balance factor maintenance.

31 | P a g e
 Conclusion:

Trees and balanced trees are essential data structures in computer science due to their
hierarchical nature and efficiency in operations like searching, insertion, and deletion. Binary
trees provide the foundation, while binary search trees enhance searching efficiency. Balanced
binary trees, such as AVL trees, ensure that operations remain efficient even under worst-case
scenarios by maintaining a balanced structure through rotations. This combination of properties
makes them ideal for use in databases, search engines, and many real-time applications.

 GRAPHS, HEAP AND HASHING:


32 | P a g e
 GRAPHS:

Graphs are a versatile data structure used to represent a set of objects and their relationships.
A graph is defined by two main components: vertices (or nodes) and edges (or links). Graphs
can be either directed (where the edges have a direction) or undirected (where the edges have
no direction). They can also be weighted (where each edge has a weight or cost associated
with it) or unweighted.

Key Concepts:

 Vertex (Node): A fundamental unit of the graph that stores data or represents an entity.

 Edge (Link): A connection between two vertices, representing the relationship between
them.

 Degree: The number of edges incident on a vertex. In directed graphs, there are in-
degree (number of incoming edges) and out-degree (number of outgoing edges).
33 | P a g e
 Path: A sequence of edges connecting two vertices.

 Cycle: A path that starts and ends at the same vertex without repeating any edge.

 Graph Representation:

1. Adjacency Matrix:

 A 2D matrix where rows and columns represent vertices. An entry at position (i,
j) is 1 if there is an edge between vertex i and vertex j, otherwise, it is 0.

 Pros: Efficient for dense graphs; constant-time edge lookup (O(1)).

 Cons: Requires O(V^2) space, inefficient for sparse graphs.

2. Adjacency List:

 An array of lists where each index corresponds to a vertex, and the list at that
index contains all the vertices it is connected to by edges.

 Pros: Space-efficient for sparse graphs (O(V + E) space).

 Cons: Edge lookup takes O(V) in the worst case.

3. Edge List:

34 | P a g e
 A list of all the edges in the graph, each edge represented as a pair (or triplet if
weighted) of vertices.

 Pros: Simple and compact.

 Cons: Inefficient for most graph operations like searching for adjacent vertices.

 Graph Traversal Algorithms:

Graph traversal algorithms are used to visit all the vertices and edges of a graph. The two
primary traversal techniques are Breadth-First Search (BFS) and Depth-First Search (DFS).

1. Breadth-First Search (BFS):

 BFS explores the graph level by level. Starting from a source node, it first visits
all the neighbouring nodes at the current level before moving to the next level.

 Implementation: BFS uses a queue to keep track of the nodes to be visited next.

 Applications:

 Finding the shortest path in unweighted graphs.

 Crawling through web pages (e.g., search engines).


35 | P a g e
 Solving puzzles like finding the shortest path in a maze.

 Time Complexity: O(V + E), where V is the number of vertices and E is the
number of edges.

2. Depth-First Search (DFS):

 DFS explores the graph by going as deep as possible along each branch before
backtracking. It uses a stack (or recursion) to keep track of the visited nodes.

 Implementation: DFS can be implemented using either recursion or an explicit


stack.

 Applications:

 Detecting cycles in a graph.

 Topological sorting in Directed Acyclic Graphs (DAGs).

 Solving problems like mazes, puzzles, and connected components in a graph.

 Time Complexity: O(V + E).

36 | P a g e
 Heap Data Structure:

A Heap is a complete binary tree where each node satisfies the heap property. The heap
property ensures that for a Max-Heap, the value of each node is greater than or equal to the
values of its children, and for a Min-Heap, the value of each node is smaller than or equal to
the values of its children.

 Types of Heaps:

1. Min-Heap:

 The smallest element is at the root, and each parent node is smaller than its
children. This structure is useful for implementing priority queues.

 Use Cases: Dijkstra's algorithm for finding the shortest path, priority queues.

2. Max-Heap:

37 | P a g e
 The largest element is at the root, and each parent node is larger than its children.
This structure is used in algorithms like heapsort.

 Use Cases: Heapsort, scheduling problems where maximum priority elements


need to be processed first.

 Heap Operations:

1. Insertion:

 Insert a new element at the end of the heap and then "bubble up" (or "heapify up")
the element to maintain the heap property (O(log n) time complexity).

2. Deletion (Extract Root):

38 | P a g e
 Remove the root (smallest or largest element) and replace it with the last element.
Then, "bubble down" (or "heapify down") the new root to restore the heap
property (O(log n)).

3. Peek:

 Simply return the root element (min or max) without modifying the heap. This
operation takes constant time O(1).

4. Heapify:

 The process of transforming a binary tree into a heap. This can be done
in O(n) time.

 Applications of Heaps:

 Priority Queues: Heaps are the basis for efficiently implementing priority queues.

 Sorting Algorithms: Heapsort uses the heap structure to sort elements in O(n log n) time.

 Scheduling: Used in systems that require elements to be processed based on priority.

39 | P a g e
 Hashing:

Hashing is a technique used to efficiently store and retrieve data by mapping it to a location
in a table using a hash function. The primary goal of hashing is to achieve constant time
complexity O(1) for insertions, deletions, and lookups.

 Hash Functions:

 A hash function maps an input (key) to a fixed-size integer (hash value). Ideally, the hash
function distributes keys uniformly across the hash table to minimize collisions.

 Good Hash Function Characteristics:

 Efficient computation.

 Uniform distribution to minimize collisions.

 Minimized clustering of keys in specific table slots.

 Applications of Hashing:

 Databases: Hashing is widely used in database indexing to provide quick access to


records.

 Caching: Hash tables are used in cache systems to store frequently accessed data for
faster retrieval.

40 | P a g e
 Cryptography: Hash functions are fundamental to cryptographic algorithms, used in
hashing passwords, digital signatures, and data integrity checks.

 Compiler Design: Symbol tables in compilers are implemented using hash tables for fast
lookups of variable names, constants, and functions.

 Conclusion:

The topics of graphs, heaps, and hashing are central to many areas of computer science.
Graphs model complex relationships between data points, while traversal algorithms like
BFS and DFS allow us to explore and analyze these connections. Heaps provide efficient
priority handling and are critical to algorithms like heapsort and scheduling. Hashing delivers
fast and efficient data retrieval, making it indispensable in database systems, cryptography,
and other applications. Understanding these structures and their operations is key to
developing efficient software solutions.

41 | P a g e
 SEARCHING, SORTING AND PROJECT:

 Searching Algorithms:
1. Linear Search:
 Description: This is the simplest searching algorithm that checks each element in
the array sequentially until the desired element is found or the entire array has
been searched.
 Time Complexity: O(n) in the worst and average cases, where n is the number of
elements in the array.
 Space Complexity: O(1) since no additional space is required.
 Use Case: Best used when the array is unsorted or for small datasets.

2. Binary Search:
 Description: Binary Search works on a sorted array by repeatedly dividing the
search interval in half. It compares the target value with the middle element of the
array and eliminates half of the remaining elements from consideration.
 Time Complexity: O(log n) in the worst and average cases.
 Space Complexity: O(1) for iterative implementation, O(log n) for recursive
implementation due to stack space.
 Use Case: Efficient for large, sorted datasets.

42 | P a g e
 Sorting Algorithms:
1. Bubble Sort:
 Description: A simple comparison-based sorting algorithm that repeatedly steps
through the list, compares adjacent elements, and swaps them if they are in the
wrong order.
 Time Complexity: O(n^2) in the worst and average cases.
 Space Complexity: O(1).
 Use Case: Suitable for small datasets or when the list is almost sorted.

43 | P a g e
 Selection Sort:
 Description: This algorithm divides the array into a sorted and unsorted part,
repeatedly selecting the smallest (or largest) element from the unsorted part and
moving it to the sorted part.
 Time Complexity: O(n^2) in the worst and average cases.
 Space Complexity: O(1).
 Use Case: Best for small arrays and when memory is a constraint.

2. Insertion Sort:
 Description: Builds the sorted array one item at a time by repeatedly picking the
next element and inserting it into its correct position among the already sorted
elements.
 Time Complexity: O(n^2) in the worst case, but O(n) for nearly sorted arrays.
 Space Complexity: O(1).
 Use Case: Efficient for small or nearly sorted arrays.

44 | P a g e
3. Merge Sort:
 Description: A divide-and-conquer algorithm that divides the array into halves,
recursively sorts each half, and then merges the sorted halves.
 Time Complexity: O(n log n) in all cases.
 Space Complexity: O(n) due to the use of temporary arrays during merging.
 Use Case: Suitable for large datasets and when stability is important.

45 | P a g e
 Quick Sort:
 Description: Another divide-and-conquer algorithm that selects a "pivot" element
and partitions the array into two sub-arrays, such that elements less than the pivot
come before it and elements greater than the pivot come after. The process is
recursively applied to the sub-arrays.
 Time Complexity: O(n log n) on average, but O(n^2) in the worst case.
 Space Complexity: O(log n) due to recursion.
 Use Case: Often the fastest general-purpose sorting algorithm for large datasets,
despite its worst-case behaviour.

 Analysis of Sorting and Searching Algorithms:

 Time Complexity: Refers to the amount of time an algorithm takes to run as a function
of the size of the input. It's essential for comparing the efficiency of algorithms. For
example:
 Linear Search: O(n) for searching an unsorted list.

46 | P a g e
 Binary Search: O(log n) for a sorted list.
 Merge Sort: O(n log n) for guaranteed efficiency, regardless of input.
 Bubble Sort/Insertion Sort/Selection Sort: O(n^2) for worst and average cases.

 Space Complexity: Refers to the amount of memory an algorithm uses relative to the
input size.
 Linear and Binary Search: Both have O(1) space complexity, with no additional
memory required.
 Merge Sort: Requires O(n) space due to additional storage needed for merging.
 Quick Sort: Uses O(log n) space due to the recursion stack.

47 | P a g e
CHAPTER-3 THE PROJECT:

To-Do List Manager:

Source code:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main() {
vector<string> todoList;
int choice;
string task;

while (true) {
cout << "\n1. Add Task\n2. View List\n3. Delete Task\n4. Exit\nChoose an option: ";
cin >> choice;
cin.ignore(); // Ignore newline left in buffer

if (choice == 1) {
cout << "Enter task: ";
getline(cin, task);
todoList.push_back(task);
} else if (choice == 2) {
for (size_t i = 0; i < todoList.size(); ++i)
cout << i + 1 << ". " << todoList[i] << "\n";
} else if (choice == 3) {

48 | P a g e
cout << "Enter task number to delete: ";
int taskNumber;
cin >> taskNumber;
if (taskNumber > 0 && taskNumber <= todoList.size())
todoList.erase(todoList.begin() + taskNumber - 1);
else
cout << "Invalid task number.\n";
} else if (choice == 4) {
break;
} else {
cout << "Invalid choice. Please try again.\n";

}
}

49 | P a g e
 Output of the code executed:

50 | P a g e
 Conclusion:
The development of the To-Do List Manager has been a rewarding experience,
providing practical exposure to key programming concepts such as data structures,
user interface design, and file handling. This project effectively showcases the use of
arrays and linked lists to store and manage tasks, and demonstrates an intuitive
approach to implementing core operations such as adding, editing, deleting, and
marking tasks as completed.

51 | P a g e
Through this project, I gained a deeper understanding of the importance of efficient
data organization and user experience design. Additionally, handling various edge cases,
such as ensuring data persistence across sessions and maintaining a flexible user
interface, allowed me to strengthen my problem-solving skills.

In conclusion, the To-Do List Manager successfully meets the goals of task management,
providing a simple and user-friendly platform for users to organize their daily activities.
This project has laid a solid foundation for future enhancements, such as integrating
advanced features like task prioritization, reminders, and synchronization across devices,
making it a valuable learning experience that bridges theoretical knowledge with
practical implementation.

 Bibliography:

 Mark Allen Weiss – "Data Structures and Algorithm Analysis in C++" (4th Edition,
2014)

 Robert Lafore – "Data Structures and Algorithms in Java/C++" (2nd Edition, 2002)

52 | P a g e
 Websites:

 https://www.geeksforgeeks.org/data-structures/

 https://www.learncpp.com/

 https://www.tutorialspoint.com/data_structures_algorithms/index.

53 | P a g e

You might also like