5 Marks Question
5 Marks Question
1. Apply Bubble sort to sort the following numbers: 14, 33, 27, 35, 10.
Bubble sort works by repeatedly comparing adjacent elements and swapping them if they are in the
wrong order. The algorithm continues to perform passes over the list until the entire list is sorted.
Pass 1:
Pass 2:
Pass 3:
Pass 4:
1. Infix: A + (B * C) / D
9. ): Closing parenthesis, pop until opening parenthesis. Pop *, add to postfix expression → A B
C*
12. End of expression, pop the remaining operators (/) and add to postfix expression → A B C * D
/+
Postfix Expression: A B C * D / +
3. Write an algorithm to insert an item in a Queue data structure and explain each step.
2. Check for Full Queue: Before inserting an item, check if the queue is full (if it is, return an
error).
3. Insert Item:
o If the queue is not full, insert the item at the rear end (or tail) of the queue.
4. Handle Circular Queue (if applicable): In the case of a circular queue, when the rear pointer
reaches the end of the array, reset it to the beginning of the array.
Example Code:
class Queue:
self.front = self.rear = -1
self.size = size
return
self.front = self.rear = 0
else:
self.queue[self.rear] = item
4. Construct a maximum heap tree from the following sequence of inputs: 45, 32, 50, 22, 65, 55, 77
1. Insert 45 → [45]
77
/ \
65 55
/ \ / \
50 22 45 32
5. Write an algorithm for Quick Sort and Heap Sort and explain.
1. Choose a pivot element from the array (usually the last element).
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) - 1]
2. Swap the root (maximum value) with the last element of the heap.
largest = i
left = 2 * i + 1
right = 2 * i + 2
largest = left
largest = right
if largest != i:
heapify(arr, n, largest)
def heap_sort(arr):
n = len(arr)
heapify(arr, n, i)
for i in range(n-1, 0, -1):
heapify(arr, i, 0)
6. Create an algorithm for Push and Pop operations on Stack using Arrays
o Increment the top pointer and place the element at the top.
Push Algorithm:
if top == len(stack) - 1:
print("Stack Overflow")
return top
top += 1
stack[top] = element
return top
Pop Algorithm:
if top == -1:
print("Stack Underflow")
return top
top -= 1
return top
7. Define Stack. What are the various Operations performed on the Stack?
Stack: A stack is a linear data structure that follows the Last In, First Out (LIFO) principle. The most
recent element added is the first to be removed.
Operations on Stack:
8. Draw and explain Adjacency Matrix and mention the advantages of adjacency matrix
Adjacency Matrix is a 2D array used to represent a graph. If a graph has VVV vertices, an adjacency
matrix is a V×VV \times VV×V matrix. The value at position (i,j)(i, j)(i,j) represents the presence or
absence of an edge between vertex iii and vertex jjj.
For undirected graphs, if there is an edge between iii and jjj, then both (i,j)(i, j)(i,j) and (j,i)(j,
i)(j,i) are set to 1.
For directed graphs, the value (i,j)(i, j)(i,j) is 1 if there is a directed edge from vertex iii to
vertex jjj, and 0 otherwise.
Example:
For the undirected graph with 4 vertices (A, B, C, D) and the edges A-B, A-C, and B-D:
mathematica
Copy code
Graph:
/\
B C
Adjacency Matrix:
ABCD
A[0110]
B[1001]
C[1000]
D[0100]
Advantages of Adjacency Matrix:
1. Efficient Edge Lookup: It provides O(1)O(1)O(1) time complexity for checking if an edge exists
between two vertices.
2. Space Efficiency for Dense Graphs: If the graph is dense (i.e., most pairs of vertices are
connected), the adjacency matrix is an efficient representation.
9. Explain the Pre-order, In-order, and Post-order traversal in Tree data structure
1. Pre-order Traversal:
o Visit the root node first, then recursively traverse the left subtree, followed by the
right subtree.
css
Copy code
/\
B C
Pre-order traversal: A, B, D, C
2. In-order Traversal:
o Recursively traverse the left subtree first, then visit the root node, and finally
traverse the right subtree.
3. Post-order Traversal:
o Recursively traverse the left subtree, then the right subtree, and finally visit the root
node.
Postfix expression: 5 6 * 24 2 3 ^ / -
Steps to evaluate:
3. Read * → Pop 6 and 5, multiply them → 5 * 6 = 30, Push the result → Stack: [30]
7. Read ^ → Pop 3 and 2, calculate 2^3 = 8, Push the result → Stack: [30, 24, 8]
8. Read / → Pop 8 and 24, calculate 24 / 8 = 3, Push the result → Stack: [30, 3]
9. Read - → Pop 3 and 30, calculate 30 - 3 = 27, Push the result → Stack: [27]
Final Result: P = 27
11. Construct a BST with the following input values: 70, 20, 11, 45, 95, 76, 29, 59, 99
3. Insert 11: 11 is less than 70, less than 20, so it goes to the left of 20.
4. Insert 45: 45 is less than 70 but greater than 20, so it goes to the right of 20.
6. Insert 76: 76 is greater than 70 but less than 95, so it goes to the left of 95.
7. Insert 29: 29 is less than 70, greater than 20, but less than 45, so it goes to the left of 45.
8. Insert 59: 59 is less than 70, greater than 45, so it goes to the right of 45.
9. Insert 99: 99 is greater than 70, greater than 95, so it goes to the right of 95.
BST Structure:
markdown
Copy code
70
/ \
20 95
/ \ / \
11 45 76 99
/ \
29 59
B-Tree is a self-balancing tree data structure that maintains sorted data and allows efficient insertion,
deletion, and search operations. It is commonly used in databases and file systems.
Characteristics of a B-Tree:
2. Nodes Contain Multiple Keys: Each node can have multiple keys and children.
3. Sorted Keys: Keys within each node are sorted in ascending order.
4. Root Node: The root node can have as few as one child or be empty.
5. Nodes with Multiple Children: A node with nnn keys will have n+1n+1n+1 children.
6. Efficient Operations: All operations (insert, delete, search) have O(logn)O(\log n)O(logn) time
complexity.
13. What is a Linked List? Write and explain the algorithm for create, insertion, and traverse
operations in a doubly linked list with an example.
A Linked List is a linear data structure in which elements are stored in nodes. Each node contains
data and a reference (or link) to the next node in the sequence.
In a Doubly Linked List, each node has two references: one to the next node and one to the previous
node.
Copy code
class Node:
self.data = data
self.next = None
self.prev = None
class DoublyLinkedList:
def __init__(self):
self.head = None
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
new_node.next = self.head
self.head.prev = new_node
self.head = new_node
def traverse(self):
current = self.head
while current:
current = current.next
Example Operations:
python
Copy code
dll = DoublyLinkedList()
dll.insert_at_beginning(10)
dll.insert_at_beginning(20)
dll.traverse() # Output: 20 10
14. What is Stack? Write algorithm for operations of stack with examples
Refer to the Stack section above for a complete explanation of Stack and its operations.
15. What are the limitations of Queue? Explain the algorithms for various operations of circular
queue
1. Fixed size: In simple queues, the size is fixed and may lead to overflow or underutilization.
2. No direct access: You can only access the front and rear elements, not any arbitrary element.
In Circular Queue, these limitations are resolved by using the available space more efficiently.
Circular queue operates in a circular manner, where the end of the queue connects back to the front.
An AVL Tree is a self-balancing binary search tree (BST) in which the difference in heights between
the left and right subtrees (balance factor) of any node is at most 1. The key operations in AVL trees
are insertion, deletion, and searching. Here's how each operation works:
1. BST Insertion: First, insert the node in the tree as you would in a standard binary search tree
(i.e., if the value is less than the current node, insert in the left subtree, otherwise insert in
the right subtree).
2. Balance Factor Calculation: After inserting the node, traverse back from the inserted node to
the root, calculating the balance factor at each node. The balance factor is the difference
between the heights of the left and right subtrees (balance_factor = height(left subtree) -
height(right subtree)).
3. Balancing the Tree: If the balance factor of any node becomes greater than 1 or less than -1,
the tree is unbalanced, and you need to perform rotations:
o Left-Left (LL) Case: If the left child of the left subtree is higher, perform a Right
Rotation.
o Right-Right (RR) Case: If the right child of the right subtree is higher, perform a Left
Rotation.
o Left-Right (LR) Case: If the right child of the left subtree is higher, perform a Left
Rotation on the left child followed by a Right Rotation on the current node.
o Right-Left (RL) Case: If the left child of the right subtree is higher, perform a Right
Rotation on the right child followed by a Left Rotation on the current node.
1. BST Deletion: First, delete the node from the tree as you would in a standard binary search
tree (find the node, replace it with its in-order predecessor or successor if necessary, and
remove it).
2. Balance Factor Calculation: After deletion, traverse back from the parent node to the root,
recalculating the balance factor at each node.
3. Balancing the Tree: If the balance factor becomes greater than 1 or less than -1 at any node,
perform rotations to restore the balance:
o Similar to insertion, you will need to perform rotations based on whether the tree is
left-heavy or right-heavy at any node.
Searching in an AVL tree is similar to searching in a regular binary search tree. Starting from
the root, if the search value is less than the current node's value, move to the left child; if it’s
greater, move to the right child.
Since an AVL tree is balanced, searching will take O(log n) time, where n is the number of
nodes in the tree.
17. What is a Binary Search Tree? How do you insert an element into a Binary Search Tree?
A Binary Search Tree (BST) is a binary tree in which every node has at most two children, and the
following conditions hold:
The value of every node in the left subtree is less than the value of the root node.
The value of every node in the right subtree is greater than the value of the root node.
o If the element to be inserted is smaller than the current node’s value, move to the
left child.
o If the element to be inserted is greater than the current node’s value, move to the
right child.
3. Insert the Node: Once a null (empty) child is reached, insert the new node at that position.
4. Maintain BST Property: Ensure that the BST properties are maintained by continuing the
traversal until a valid insertion point is found.
Example:
30
/ \
20 40
/ \
10 25
Insert 25:
Floyd's Algorithm, also known as Floyd-Warshall Algorithm, is a well-known algorithm used to find
the shortest paths between all pairs of vertices in a weighted graph (with both positive and negative
weights). It is a dynamic programming algorithm and works for both directed and undirected graphs.
1. Initialization:
o Initialize a distance matrix dist[i][j] where dist[i][j] is the shortest path from vertex i
to vertex j.
o If there is an edge between vertex i and j, set dist[i][j] to the edge weight; if no edge
exists, set dist[i][j] to infinity (∞).
o The key idea is that, for each intermediate vertex k, check if a path from vertex i to
vertex j that goes through k is shorter than the existing path.
o The update rule is: dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j])dist[i][j] = \min(dist[i][j],
dist[i][k] + dist[k][j])
3. Result:
o After processing all vertices as intermediates, the matrix dist[i][j] contains the
shortest path lengths between all pairs of vertices.
Time Complexity:
The time complexity of Floyd's algorithm is O(V3)O(V^3), where V is the number of vertices
in the graph. This is because there are three nested loops (for each of the vertices) iterating
over the graph.
Warshall’s Algorithm is used to find the transitive closure of a directed graph. The transitive closure
of a graph is a matrix that shows which vertices are reachable from other vertices. It’s essentially a
special case of Floyd’s algorithm where the goal is to determine reachability (whether a path exists)
rather than shortest path distances.
1. Initialization:
o Start with an adjacency matrix A where A[i][j] = 1 if there is an edge from vertex i to
vertex j, otherwise A[i][j] = 0.
o Set A[i][i] = 1 for all vertices (a vertex can always reach itself).
2. Update Matrix:
o For each vertex k, update the matrix A[i][j] to reflect whether there is a path from
vertex i to vertex j through vertex k.
o The update rule is: A[i][j]=A[i][j]∨(A[i][k]∧A[k][j])A[i][j] = A[i][j] \lor (A[i][k] \land A[k]
[j]) where \lor is the logical OR operator, and \land is the logical AND operator.
3. Result:
o After completing the algorithm, A[i][j] = 1 means there is a path from vertex i to
vertex j, and A[i][j] = 0 means no such path exists.
Example:
0→1
1→2
2→3
A=[1111011100110001]A = \begin{bmatrix} 1 & 1 & 1 & 1 \\ 0 & 1 & 1 & 1 \\ 0 & 0 & 1 & 1 \\ 0 & 0 &
0 & 1 \end{bmatrix}
This matrix indicates that every vertex can reach every other vertex, either directly or indirectly.
Time Complexity: