Computer Application Data Structure
Computer Application Data Structure
STRUCTURE
System
Semester: 5 th Session: 2023
Notes Available for 8th, 9th, 10th, 11th, 12th, B.A, B.SC, I, II, III year, M.A, B. Ed, M.
Ed Manuu & Ignou classes and much more #63
9103030057
MK 5TH Semester
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 2
MMM
MK 5TH Semester
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 3
MMM
MK 5TH Semester
Primitive data structures are the most basic types of data structures provided
by programming languages. They include data types such as integers, floats,
characters, and booleans. These structures serve as the building blocks for
more complex data structures. For example, integers can be combined into
arrays, and characters can form strings. Primitive data structures are
crucial for performing fundamental operations and serve as the foundation
for algorithm development.
Non-primitive data structures are built using primitive data types and can be
classified into linear and non-linear structures. Examples include arrays,
linked lists, stacks, queues, trees, and graphs. These structures enable the
organization of complex data types and relationships. Non-primitive data
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 4
MMM
MK 5TH Semester
structures are essential for implementing algorithms that require more than
simple data manipulation, such as sorting and searching operations.
Algorithm Complexity
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 5
MMM
MK 5TH Semester
Conclusion
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 6
MMM
MK 5TH Semester
Linear Search: This algorithm checks each element sequentially until the
desired element is found or the end of the array is reached. It has a time
complexity of O(n).
Binary Search: This algorithm is more efficient but requires the array to be
sorted. It divides the search interval in half repeatedly, resulting in a time
complexity of O(log n).
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 7
MMM
MK 5TH Semester
elements, a for loop iterates from the first to the last index, accessing each
element.
3. Inserting: Inserting an element into an array involves placing a new
element at a specified index, which may require shifting subsequent elements
to maintain order:
If the array is not full, you can insert an element by specifying its index,
shifting elements as necessary.
Inserting at the end of the array is straightforward if there is available
space, while inserting at the beginning or in the middle requires more effort
and has a time complexity of O(n).
Once the target element is identified, all elements after it are shifted left,
effectively removing the element.
Like insertion, the time complexity for deletion is also O(n) due to the
potential need to shift elements.
Two-Dimensional Arrays
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 8
MMM
MK 5TH Semester
represents the row index and j represents the column index. Two-
dimensional arrays are widely used in applications like image processing,
scientific simulations, and game development.
Sparse Matrices
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 9
MMM
MK 5TH Semester
Recursion
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 10
MMM
MK 5TH Semester
Example of Recursion
def factorial(n):
if n == 0: # Base case
return 1
else: # Recursive case
return n * factorial(n - 1)
In this example, the function continues to call itself with a decremented value
of until it reaches the base case of zero, at which point it returns 1.
Conclusion
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 11
MMM
MK 5TH Semester
Linear Search
Algorithm Steps:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 12
MMM
MK 5TH Semester
Time Complexity:
Best Case: O(1) (when the target element is the first element)
Worst Case: O(n) (when the target element is at the end or not present)
Space Complexity: O(1) (only a few variables are used)
Advantages:
Simple to implement.
Does not require the array to be sorted.
Disadvantages:
Inefficient for large datasets due to its linear time complexity.
Binary Search
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 13
MMM
MK 5TH Semester
Algorithm Steps:
1. Start with two pointers, one at the beginning (low) and one at the end
(high) of the sorted array.
2. Calculate the middle index: mid = (low + high) / 2.
3. Compare the middle element with the target value:
If the target is greater than the middle element, narrow the search to the
upper half by setting low = mid + 1.
4. Repeat steps 2-3 until the target is found or the search interval is empty.
Time Complexity:
Best Case: O(1) (when the target is the middle element)
Average Case: O(log n) (where n is the number of elements)
Worst Case: O(log n) (when the search interval is reduced to one element)
Space Complexity: O(1) for the iterative version and O(log n) for the
recursive version due to the call stack.
Advantages:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 14
MMM
MK 5TH Semester
Requires the array to be sorted, which may involve additional time and
space for sorting.
Comparison of Linear Search and Binary Search
Conclusion
In conclusion, both linear search and binary search are essential algorithms
for locating elements in data structures. Linear search is simple and works
on unsorted data, making it useful for smaller datasets. In contrast, binary
search is much more efficient for larger, sorted datasets but requires an
initial sorting step. Choosing the appropriate algorithm depends on the
context, size of the dataset, and whether the data is sorted. Understanding
these algorithms is fundamental for optimizing search operations in software
development and data processing tasks.
Unit-II: Linear Data Types - II
Q.Array Sorting Algorithms: Selection sort. Insertion sort, Bubble Sort,
Quick sort.Stack: Definition & Concepts
Ans.Array Sorting Algorithms
Selection Sort
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 15
MMM
MK 5TH Semester
Algorithm Steps:
1. Start with the first element of the array. Assume it is the minimum.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 16
MMM
MK 5TH Semester
Algorithm Steps:
1. Start from the second element (the first element is considered sorted).
2. Compare the current element with the previous elements.
3. Shift all larger elements one position to the right.
4. Insert the current element into its correct position.
5. Repeat steps 2-4 for all elements in the array until the entire array is
sorted.
Time Complexity:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 17
MMM
MK 5TH Semester
Simple to implement.
Disadvantages:
Inefficient for large datasets due to its quadratic time complexity.
Bubble Sort
Bubble Sort is 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.
Algorithm Steps:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 18
MMM
MK 5TH Semester
Disadvantages:
Quick Sort
Algorithm Steps:
1. Choose a "pivot" element from the array. Various methods can be used to
select the pivot, such as the first element, the last element, or the median.
2. Partition the array into two halves: elements less than the pivot and
elements greater than the pivot.
3. Recursively apply the above steps to the sub-arrays of elements less than
and greater than the pivot.
4. Combine the sorted sub-arrays and the pivot to form the final sorted
array.
Time Complexity:
Best Case: O(n log n) (when the pivot divides the array into two equal
halves)
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 19
MMM
MK 5TH Semester
Generally faster and more efficient for large datasets compared to other
algorithms.
In-place sorting with low memory usage.
Disadvantages:
The worst-case performance can be poor if not implemented correctly.
Not stable (equal elements may not maintain their relative order).
Summary of Sorting Algorithms
Sorting algorithms serve crucial roles in computer science, allowing for the
organization of data for more efficient searching and processing. While
Selection Sort, Insertion Sort, and Bubble Sort are easy to understand and
implement, they may not be suitable for large datasets due to their quadratic
time complexity. Quick Sort, on the other hand, provides a more efficient
alternative for larger arrays through its divide-and-conquer strategy.
Understanding these sorting algorithms, their complexities, and their best-
use cases is essential for anyone working with data in programming or
software development.
A stack is a linear data structure that follows the Last In, First Out (LIFO)
principle. This means that the last element added to the stack will be the first
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 20
MMM
MK 5TH Semester
1. Push: Adds an element to the top of the stack. This operation increases the
stack size by one.
2. Pop: Removes the top element from the stack. If the stack is empty, this
operation may result in an error (underflow).
3. Peek (or Top): Retrieves the value of the top element without removing it
from the stack. This operation allows the user to inspect the top element.
4. IsEmpty: Checks whether the stack is empty. This operation returns true if
there are no elements in the stack and false otherwise.
5. Size: Returns the number of elements currently in the stack.
Implementation of a Stack
Stacks can be implemented in two primary ways:
1. Array-based Implementation:
This method uses a fixed-size array to store the stack elements.
A variable tracks the index of the top element.
When the stack is full, attempting to push another element results in an
overflow error.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 21
MMM
MK 5TH Semester
This method uses a linked list where each node contains the stack element
and a reference to the next node.
The top of the stack corresponds to the head of the linked list, allowing for
dynamic resizing without overflow.
Applications of Stacks
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 22
MMM
MK 5TH Semester
Stacks can be represented in various ways, with one of the most common
being the array representation. This method utilizes a fixed-size array to
store stack elements, where a variable indicates the index of the top element
in the stack.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 23
MMM
MK 5TH Semester
Example:
2. Pop:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 24
MMM
MK 5TH Semester
When an element is popped from the stack, the element at the index indicated
by top is returned, and top is decremented.
A check is performed to ensure the stack is not empty (i.e., top >= 0).
Example:
def pop(stack, top):
if top >= 0:
element = stack[top]
top -= 1
return element
else:
print("Stack Underflow")
3. Peek:
This operation retrieves the top element without modifying the stack. It
checks if the stack is empty before accessing the element.
Example:
4. IsEmpty:
This function checks if the stack is empty by returning true if top is -1.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 25
MMM
MK 5TH Semester
Example:
def is_empty(top):
return top == -1
5. Size:
This function returns the current size of the stack by adding one to top.
Example:
def size(top):
return top + 1
Applications of Stack
1. Infix Notation:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 26
MMM
MK 5TH Semester
Parentheses are not needed to enforce order because the operator's position
indicates the order of evaluation.
3. Postfix Notation (Reverse Polish Notation):
Like prefix notation, postfix notation avoids ambiguity and eliminates the
need for parentheses.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 27
MMM
MK 5TH Semester
Reverse: C * B + A
4. If the token is an operator, pop operators from the stack to the output until
the top of the stack has an operator of less precedence or the stack is empty.
Then push the current operator onto the stack.
6. If the token is a right parenthesis ), pop from the stack to the output until a
left parenthesis is at the top of the stack. Remove the left parenthesis from
the stack.
7. After scanning the expression, pop any remaining operators from the stack
to the output.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 28
MMM
MK 5TH Semester
Stacks are essential for evaluating postfix and prefix expressions due to their
sequential nature.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 29
MMM
MK 5TH Semester
Push B → Stack: A, B
Operator + → Pop A and B, calculate A + B, push result back.
Push C → Stack: A+B, C
Operator * → Pop A+B and C, calculate (A + B) * C.
5. If the token is an operator, pop the top two operands from the stack, apply
the operator, and push the result back onto the stack.
6. After scanning, the final result will be at the top of the stack.
Example: For the prefix expression *+ABC, the steps are:
Reverse: C B A + *
Push C → Stack: C
Push B → Stack: C, B
Push A → Stack: C, B, A
Operator + → Pop A and B, calculate B + A, push result back.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 30
MMM
MK 5TH Semester
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 31
MMM
MK 5TH Semester
To add an element to the queue, the rear pointer is incremented, and the
element is placed at the new rear index.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 32
MMM
MK 5TH Semester
Before adding, a check is performed to ensure the queue is not full (i.e., rear
< max_size - 1).
Example:
This operation retrieves the front element without modifying the queue. A
check is performed to ensure the queue is not empty.
Example:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 33
MMM
MK 5TH Semester
4. IsEmpty:
This function checks if the queue is empty by returning true if front > rear.
Example:
Circular Queue
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 34
MMM
MK 5TH Semester
allows for efficient utilization of the array space, especially when elements
are dequeued.
1. Enqueue:
When adding an element, the rear pointer is incremented in a circular
manner (using modulo operation).
Before adding, a check is performed to ensure the queue is not full.
Example:
def enqueue(circular_queue, front, rear, element):
if (rear + 1) % max_size != front: # Check for full
rear = (rear + 1) % max_size
circular_queue[rear] = element
else:
print("Queue is full")
2. Dequeue:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 35
MMM
MK 5TH Semester
Example:
def dequeue(circular_queue, front, rear):
if front != rear: # Check for empty
element = circular_queue[front]
front = (front + 1) % max_size
return element
else:
print("Queue is empty")
Applications of Queue
Queues have numerous applications in computer science and programming,
largely due to their FIFO nature. Some notable applications include:
1. Process Scheduling:
In operating systems, queues are used for managing processes in scheduling
algorithms. Processes are added to a queue and executed in the order they
arrive, ensuring fair CPU time allocation.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 36
MMM
MK 5TH Semester
2. Data Buffering:
Queues are commonly used in buffering data streams. For example, a printer
queue holds print jobs until they are processed in the order they were
received.
BFS is a graph traversal algorithm that uses queues to explore nodes level
by level. Nodes are added to the queue as they are discovered, allowing for
systematic exploration of all neighbors.
4. Asynchronous Data Processing:
Conclusion
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 37
MMM
MK 5TH Semester
Accessing the members of a structure is done using the dot operator (.) when
dealing with structure variables. For instance, if we have a structure
variable person, we can access the name using person.name. If a structure
variable is created through a pointer, the arrow operator (->) is used. This
allows for easy manipulation of structure data, whether directly or via
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 38
MMM
MK 5TH Semester
Pointers are variables that store the memory address of another variable.
They provide powerful capabilities in C and C++ programming, such as
dynamic memory management, the ability to manipulate arrays, and the
creation of complex data structures like linked lists and trees. Pointers can
significantly enhance performance and memory efficiency by enabling direct
access to memory locations. Additionally, they allow functions to modify
variables defined outside their scope, which is critical for various
programming applications.
When combined, structures and pointers enable even more flexibility in data
management. Pointers to structures can be used to dynamically allocate
memory for structures, which is essential when the number of required
structures is not known at compile time. Using pointers to structures allows
programmers to pass large structures to functions efficiently without the
overhead of copying entire structures. For example, passing a pointer to a
Person structure instead of the entire structure saves memory and processing
time.
Conclusion
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 39
MMM
MK 5TH Semester
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 40
MMM
MK 5TH Semester
A singly linked list is a type of linked list where each node contains two
components: the data and a pointer to the next node in the sequence. The
first node is referred to as the head, and the last node points to null,
indicating the end of the list. This one-way link structure allows for efficient
traversal in a single direction (from head to tail), making operations like
insertion and deletion straightforward. However, it does not allow for
backward traversal, which can be a limitation in certain applications.
Memory Representation
1. Insertion:
Insertion can occur at three main points: the beginning, the end, or at a
specific position in the list.
To insert a node at the beginning, a new node is created, and its next pointer
is set to the current head. The head is then updated to point to the new node.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 41
MMM
MK 5TH Semester
For insertion at the end, the list is traversed until the last node is reached,
and the new node is linked to the last node’s next pointer.
To insert at a specific position, the list is traversed until the desired position
is found, and the new node’s pointers are adjusted accordingly.
2. Deletion:
Deletion can also occur at the beginning, end, or at a specified position.
To delete the first node, the head pointer is updated to point to the second
node in the list, effectively removing the first node.
Deleting the last node requires traversing the list to find the second-to-last
node, which will need its next pointer set to null.
For deletion at a specific position, the list is traversed to find the node just
before the target node, and the pointers are updated to bypass the node to be
deleted.
3. Traversal:
Traversal involves visiting each node in the linked list, typically starting
from the head and moving through each node using the next pointers until
the end of the list is reached (i.e., when a node points to null).
During traversal, operations can be performed on each node, such as
printing the data or performing calculations based on the node values.
4. Reversal:
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 42
MMM
MK 5TH Semester
Reversal of a singly linked list involves changing the direction of the next
pointers so that the last node becomes the new head, and the original head
becomes the last node with its next pointer set to null.
This operation requires maintaining three pointers: previous, current, and
next. As the list is traversed, the next pointer of the current node is updated
to point to the previous node, effectively reversing the links.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 43
MMM
MK 5TH Semester
Conclusion
Singly linked lists are fundamental data structures that provide dynamic
memory management and efficient operations for storing and manipulating
collections of data. Their unique characteristics and flexibility make them
suitable for a wide range of applications in computer science, from basic
data structure implementations to complex systems like file management and
graph representations. Understanding singly linked lists, their operations,
and their applications is essential for any aspiring programmer or computer
scientist.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 44
MMM
MK 5TH Semester
linked lists. Each has unique characteristics that allow for specific
operations and optimizations.
Doubly Linked List
A doubly linked list is a variation of the standard linked list in which each
node contains three components: the data, a pointer to the next node, and a
pointer to the previous node. This means that each node can be traversed in
both directions (forward and backward). The first node is still called the
head, and the last node points to null for both next and previous pointers.
Advantages:
Insertion Flexibility: Insertion can be done more easily at both the front and
the back, as well as at any position, since both previous and next pointers
can be easily manipulated.
Operations:
1. Insertion: Similar to singly linked lists, but requires updating both the next
and previous pointers of the adjacent nodes.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 45
MMM
MK 5TH Semester
A circular linked list is a variation where the last node points back to the
first node, forming a circle. Circular linked lists can be either singly or
doubly linked. In a singly circular linked list, each node has a next pointer
pointing to the subsequent node, while in a doubly circular linked list, each
node has both next and previous pointers.
Advantages:
Efficient Use of Memory: Circular linked lists can efficiently utilize memory
by avoiding null pointers at the end of the list, which can be beneficial in
certain applications.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 46
MMM
MK 5TH Semester
Operations:
1. Insertion: Similar to singly linked lists, but when inserting at the end, the
new node’s next pointer should point to the head, and the previous last
node’s next pointer should point to the new node.
2. Deletion: Requires careful handling of the pointers to maintain the
circular structure while removing a node.
3. Traversal: Can start from any node and continue until a full loop is
completed, allowing for versatile access patterns.
Conclusion
Both doubly linked lists and circular linked lists are powerful variations of
standard linked lists, each with its advantages and suitable applications.
Doubly linked lists facilitate easier manipulation and traversal of elements in
both directions, while circular linked lists offer a continuous traversal
mechanism ideal for certain applications like queues and repeated cycles.
Understanding these variations expands the toolbox for programmers and
allows for more efficient data management in various scenarios.
A stack is a linear data structure that follows the Last In, First Out (LIFO)
principle, where the last element added is the first to be removed.
Implementing a stack using a linked list involves utilizing a singly linked list
where each node contains the stack element and a pointer to the next node.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 47
MMM
MK 5TH Semester
The head of the linked list serves as the top of the stack, enabling efficient
push and pop operations.
In this implementation, the push operation adds a new node at the head of
the list. When a new element is added, a new node is created, and its next
pointer is set to the current head. The head is then updated to point to the
new node. Conversely, the pop operation removes the node at the head. This
involves retrieving the data from the head node, updating the head to point
to the next node, and then freeing the memory of the removed node. Both
operations have a time complexity of O(1), making the linked list
implementation of the stack efficient in terms of both time and space.
A queue is another linear data structure that follows the First In, First Out
(FIFO) principle, where the first element added is the first to be removed. To
implement a queue using a linked list, a singly linked list can again be
employed, but with both a front pointer (to access the head of the list) and a
rear pointer (to access the last node). The front pointer facilitates efficient
dequeue operations, while the rear pointer allows for efficient enqueue
operations.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 48
MMM
MK 5TH Semester
removes the node at the front. This operation retrieves the data from the
front node, updates the front pointer to the next node, and frees the memory
of the removed node. Like the stack implementation, both operations for the
queue also have a time complexity of O(1).
Using linked lists for stack and queue implementations offers several
advantages. First, there is no need to define a fixed size, which addresses the
limitation of static data structures like arrays that may require resizing. The
dynamic nature of linked lists allows for efficient memory use, especially
when the number of elements fluctuates frequently. Furthermore, operations
such as insertion and deletion can be performed without shifting elements,
which is necessary in array-based implementations, making linked lists
generally more efficient for these operations.
While linked list implementations of stacks and queues offer flexibility and
efficiency, they also come with certain trade-offs. The primary concern is
memory overhead due to the storage of pointers in each node, which can be
significant in memory-constrained environments or for small data types.
Additionally, linked lists incur a slight overhead in terms of performance due
to the increased number of memory allocations and deallocations compared
to contiguous memory allocations in arrays. However, these trade-offs are
often justified in applications that require dynamic sizing and frequent
changes in the number of elements.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 49
MMM
MK 5TH Semester
Conclusion
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 50
MMM
MK 5TH Semester
Terminology
In the context of trees, several key terms are important to understand. The
root is the topmost node in the tree, while the height of a tree is the length of
the longest path from the root to a leaf. Each node in a tree can have
subtrees, which are smaller trees formed by its child nodes. The degree of a
node refers to the number of children it has. Trees can be classified into
different types based on their structure and properties, such as binary trees,
where each node has at most two children. Understanding these
terminologies is essential for effectively working with trees in various
applications.
Binary Trees
A binary tree is a specific type of tree where each node has at most two
children, referred to as the left and right child. This structure provides a
clear and efficient way to store and manipulate data. In binary trees, each
node can represent data and pointers to its child nodes, facilitating efficient
traversal and searching. Binary trees can be further categorized into several
types, including full binary trees (where each node has either 0 or 2
children), complete binary trees (where all levels are fully filled except
possibly the last), and perfect binary trees (where all leaf nodes are at the
same level).
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 51
MMM
MK 5TH Semester
Applications of Trees
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 52
MMM
MK 5TH Semester
Terminology
Graph Representation
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 53
MMM
MK 5TH Semester
Graph traversal refers to the process of visiting all the vertices and edges of
a graph. Two common traversal algorithms are Breadth-First Search (BFS)
and Depth-First Search (DFS).
BFS explores the graph level by level, starting from a selected vertex (the
root). It uses a queue data structure to keep track of vertices that need to be
explored. BFS is particularly useful for finding the shortest path in
unweighted graphs and is often used in applications such as web crawling
and social network analysis.
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 54
MMM
MK 5TH Semester
DFS, on the other hand, explores as far as possible along each branch
before backtracking. It can be implemented using recursion or a stack. DFS
is beneficial for tasks like topological sorting and cycle detection and is often
used in algorithms that require exploring all possible paths, such as maze
solving.
Dijkstra's algorithm is a widely used method for finding the shortest path
from a source vertex to all other vertices in a weighted graph. It operates by
maintaining a priority queue of vertices to explore, starting from the source
vertex with a distance of zero. As the algorithm progresses, it continually
updates the shortest known distance to each vertex, exploring the lowest-cost
paths first. Dijkstra's algorithm is particularly effective in applications like
GPS navigation systems, network routing protocols, and various
optimization problems in logistics.
Applications of Graphs
Graphs are used extensively across various domains due to their ability to
model complex relationships and structures. In computer science, they are
essential in algorithms for network routing, social network analysis, and
recommendation systems. In biology, graphs help model protein interactions
and gene regulatory networks. In transportation, graphs represent routes in
logistics and supply chain management. Moreover, they are used in artificial
intelligence for problem-solving tasks, such as planning and decision-
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 55
MMM
MK 5TH Semester
MMMMMMMMMMBBMMMMMMMMMMMMMMMMMMMMMMMMMMMM 56
MMM