MCS - 021(DSA Theory)
MCS - 021(DSA Theory)
semester
Q1. Write a program in C to accepts two polynomials as input and prints the resultant polynomial
due to the multiplication of input polynomials.
Ans:
This program assumes that the input polynomials are represented as arrays, where the index of
the array represents the power of the variable, and the value at each index represents the
coefficient for that power.
```c
#include
int main() {
int deg1, deg2;
return 0;
}
```
### Explanation:
1. **Input**: The program accepts the degree and coefficients of two polynomials.
2. **Multiplication**: It multiplies the two polynomials using a nested loop and stores the
result in a third array.
3. **Output**: The resulting polynomial is printed in the standard form.
Ans:-
C program that creates a singly linked list and performs the operations as requested:
```c
#include
#include
if (temp == NULL) {
printf("Position out of bounds\
n");
} else {
newNode->next = temp-
>next; temp->next =
newNode;
}
}
if (temp == NULL) {
printf("Node not found\n");
return;
}
prev->next = temp-
>next; free(temp);
}
if (*head ==
NULL) { return;
}
int main() {
struct Node* head =
NULL; int choice, data,
position;
do {
printf("\nLinked List Operations Menu:\
n"); printf("1. Insert at Beginning\n");
printf("2. Insert at End\n");
printf("3. Insert at Position\
n"); printf("4. Delete Node\
n");
printf("5. Display in Reverse Order\
n"); printf("6. Sort and Display\
n"); printf("7. Count Nodes\n");
printf("8. Display List\
n"); printf("9. Exit\n");
printf("Enter your choice:
"); scanf("%d", &choice);
switch
(choice) {
case 1:
printf("Enter data to insert at the
beginning: "); scanf("%d", &data);
insertAtBeginning(&head,
data); break;
case 2:
printf("Enter data to insert at the
end: "); scanf("%d", &data);
insertAtEnd(&head, data);
break;
case 3:
printf("Enter data to insert: ");
scanf("%d", &data);
printf("Enter position: ");
scanf("%d", &position);
insertAtPosition(&head, data,
position); break;
case 4:
printf("Enter the value to
delete: "); scanf("%d",
&data); deleteNode(&head,
data);
break;
case 5:
printf("Linked List in reverse
order: "); displayReverse(head);
printf("NULL\n");
break;
case 6:
printf("Sorted Linked List:
"); sortList(&head);
displayList(head);
break;
case 7:
printf("Total number of nodes: %d\n",
countNodes(head)); break;
case 8:
printf("Linked List:
");
displayList(head);
break;
case 9:
printf("Exiting...\n");
break;
default:
printf("Invalid choice! Please try again.\n");
}
} while (choice != 9);
return 0;
}
```
### Explanation:
1. **Node Structure**: A `Node` struct contains an integer `data` and a pointer to the next node.
2. **Insert Operations**:
- Insert at the beginning, end, or at a specific position.
3. **Delete Operation**: Deletes a node with the specified value.
4. **Display in Reverse**: Recursively displays the list in reverse.
5. **Sort and Display**: Sorts the list in ascending order and then displays it.
6. **Count Nodes**: Counts the total number of nodes in
```
Linked List Operations Menu:
1. Insert at Beginning
2. Insert at End
3. Insert at Position
4. Delete Node
5. Display in Reverse Order
6. Sort and Display
7. Count Nodes
8. Display List
9. Exit
Enter your choice: 1
Enter data to insert at the
beginning: 10 Linked List
Operations Menu:
...
Q3. Write a program in ‘C’ to create a doubly linked list to store integer values and
perform the following operations on it:
(i) Insert a new node at the beginning, in the middle or at the end of the linked list.
(ii)Delete a node from the linked list
(iii)Sort and display data of the doubly linked list in ascending order.
(iv)Count the number of items stored in a single linked list
(v)Calculate the sum of all even integer numbers, stored in the doubly linked list.
Ans:-
```c
#include
#include
struct Node
{ int data;
struct Node*
prev; struct
Node* next;
};
if (temp == NULL) {
printf("Node not found!\n");
return;
}
if (temp->prev != NULL) {
temp->prev->next = temp->next;
} else {
head = temp->next;
}
if (temp->next != NULL) {
temp->next->prev = temp->prev;
}
free(temp);
}
struct Node* i =
head; struct Node*
j = NULL; int temp;
while (i !=
NULL) { j = i-
>next;
while (j != NULL) {
if (i->data > j->data)
{ temp = i->data;
i->data = j-
>data; j->data
= temp;
}
j = j->next;
}
i = i->next;
}
}
// Main
function int
main() {
int choice, value, position;
do { printf("\
nMenu:\n");
printf("1. Insert at Beginning\
n"); printf("2. Insert at End\
n"); printf("3. Insert at
Middle\n"); printf("4. Delete
Node\n"); printf("5. Display
List\n"); printf("6. Sort List\
n");
printf("7. Count Nodes\n");
printf("8. Sum of Even
Numbers\n"); printf("9. Exit\
n");
printf("Enter your choice:
"); scanf("%d", &choice);
switch
(choice) {
case 1:
printf("Enter value to insert at
beginning: "); scanf("%d", &value);
insertAtBeginning(value);
break;
case
2:
printf("Enter value to insert at
end: "); scanf("%d", &value);
insertAtEnd(value);
break;
case
3:
printf("Enter value to insert in
middle: "); scanf("%d", &value);
printf("Enter position: ");
scanf("%d", &position);
insertAtMiddle(value,
position); break;
case 4:
printf("Enter value to
delete: "); scanf("%d",
&value);
deleteNode(value);
break;
case 5:
displayList();
break;
case 6:
sortList();
printf("List sorted in ascending order.\
n"); break;
case 7:
printf("Number of nodes: %d\n",
countNodes()); break;
case 8:
printf("Sum of even numbers: %d\n", sumEvenNumbers());
break;
case 9:
printf("Exiting...\n");
break;
default:
printf("Invalid choice!\n");
}
} while (choice != 9);
return 0;
}
```
### Explanation:
1. **Insert a new node**:
- At the beginning: `insertAtBeginning()`.
- At the end: `insertAtEnd()`.
- In the middle: `insertAtMiddle()` (insert at a given position).
2. **Delete a node**: The `deleteNode()` function finds the node by value and removes it.
3. **Sort and display**: The `sortList()` function sorts the list in ascending order using bubble
sort, and
`displayList()` prints the values.
4. **Count nodes**: `countNodes()` traverses the list and counts the number of nodes.
5. **Sum of even numbers**: `sumEvenNumbers()` adds up the even integers in the list.
Q4. What is a Dequeue? Write algorithm to perform insert and delete operations
in a Dequeue. Ans:-
### **What is a Dequeue?**
A **Dequeue** (also spelled **Deque**) stands for **Double-Ended Queue**, which is a linear
data structure that allows insertion and deletion of elements from both ends: the front and the
rear. Unlike a regular queue (FIFO structure), where elements are added at the rear and
removed from the front, in a dequeue, you can:
- Insert elements at the front or rear.
- Delete elements from the front or rear.
---
**Algorithm:**
1. Check if the dequeue is full.
- If full, print "Overflow" and exit.
2. If the dequeue is empty (i.e., front = -1 and rear = -1):
- Set both `front` and `rear` to 0.
3. Else, if `front == 0`:
- Set `front` to `n - 1` (wrap around to the last index if the dequeue is implemented circularly).
4. Else:
- Decrement `front` by 1.
5. Insert the element at the position `front`.
---
**Algorithm:**
1. Check if the dequeue is full.
- If full, print "Overflow" and exit.
2. If the dequeue is empty (i.e., front = -1 and rear = -1):
- Set both `front` and `rear` to 0.
3. Else, if `rear == n - 1`:
- Set `rear` to 0 (wrap around to the first index if the dequeue is implemented circularly).
4. Else:
- Increment `rear` by 1.
5. Insert the element at the position `rear`.
---
**Algorithm:**
1. Check if the dequeue is empty.
- If empty, print "Underflow" and exit.
2. If `front == rear` (i.e., only one element left):
- Set both `front` and `rear` to -1 (dequeue becomes empty).
3. Else, if `front == n - 1`:
- Set `front` to 0 (wrap around to the first index).
4. Else:
- Increment `front` by 1.
5. Remove the element from the front.
---
**Algorithm:**
1. Check if the dequeue is empty.
- If empty, print "Underflow" and exit.
2. If `front == rear` (i.e., only one element left):
- Set both `front` and `rear` to -1 (dequeue becomes empty).
3. Else, if `rear == 0`:
- Set `rear` to `n - 1` (wrap around to the last index).
4. Else:
- Decrement `rear` by 1.
5. Remove the element from the rear.
---
Consider a dequeue implemented in an array of size `n` with two pointers: `front` and `rear`.
1. **Insert 10 at the rear**: Rear is updated to hold the position, and 10 is stored.
2. **Insert 20 at the rear**: The value 20 is stored at the new rear position.
3. **Delete from the front**: The element at the front is removed.
4. **Insert 30 at the front**: Front pointer is updated, and 30 is stored at the front.
Ans:-
### (i) Pre-order: A B D E F C G
H I J K In-order: B E D F A C I H K J
G
3. For the left subtree, take the next element in pre-order: **B** is the root of the left subtree.
4. Locate B in the in-order left subtree (B E D F). Everything after B is its right subtree.
6. Moving to the right subtree of A, the next element in the pre-order is **C**, which is the
root of the right subtree.
- Left of C (in in-order): I H K J
- Right of C (in in-order): G
**H** is the next root, which has **I** and **K J** as its children based on the in-
``
`
A
/\
B
C
\\
D
G
/\\
EF
H
/\
IK
\
J
```
### (ii) Post-order: I J H D K E C L M G F B A
In-order: I H J D C K E A F L G M B
3. For the left subtree, the next root (from post-order) is **B**.
``
`
A
/\
B
F
//\
CL
G
/\ \
DE
M
/\/
IH
K
\
J
```
These trees are constructed based on recursive placement of roots and subtrees derived from
the traversal sequences.
Q6. Write a program in ‘C’ to implement a binary search tree (BST). Traverse and
display the binary search tree in the Inorder, Preorder and Post order form.
Ans:-
### C Program:
```c
#include
#include
// Main
function int
main() {
struct Node* root =
NULL; int n, value;
return 0;
}
```
### Explanation:
- **Node Structure**: Each node of the BST has a data field and two pointers (`left` and
`right`) to its left and right children.
- **Insert Function**: Inserts nodes into the BST. If the data is less than the current node's
data, it is inserted into the left subtree, otherwise, into the right subtree.
- **Traversal Functions**:
- **In-order**: Recursively visits the left subtree, the root node, and then the right subtree.
- **Pre-order**: Visits the root node first, then recursively visits the left subtree and the right
subtree.
- **Post-order**: Recursively visits the left subtree, the right subtree, and then the root node.
- **Main Function**: Takes user input to insert nodes into the BST and then prints the
```
Enter the number of nodes to
insert: 5 Enter 5 values to insert
in the BST:
50 30 20 40 70
In-order Traversal: 20 30 40 50 70
Pre-order Traversal: 50 30 20 40 70
Post-order Traversal: 20 40 30 70 50
```
This program implements a basic binary search tree and displays it in all three traversal forms:
**In-order**,
**Pre-order**, and **Post-order**.
Q7. Define AVL tree. Create an AVL tree for the following list of data if the data are
inserted in the order in an empty AVL tree.
12, 5, 15, 20, 35, 8, 2, 40, 14, 24, 27, 45, 50, 3, 4
Further delete 2, 4, 5 and 12 from the above AVL tree.
Ans:-
### Definition of an AVL Tree:
An **AVL tree** (named after its inventors Adelson-Velsky and Landis) is a **self-balancing
binary search tree**. In an AVL tree, the heights of the two child subtrees of any node differ
by at most one. If at any time the height difference becomes greater than one, rebalancing is
done to restore this property by rotating the tree.
The **height-balance property** ensures that the height of the tree remains logarithmic with
respect to the number of nodes, resulting in **O(log n)** time complexity for insertion,
deletion, and search operations.
``
`
1
2
```
``
`
1
2
/
5
```
``
`
1
2
/\
5 15
```
``
`
1
2
/\
5 15
\
2
0
```
**After balancing**:
``
`
1
2
/\
5 20
/\
15 35
```
``
`
1
2
/\
5 20
\/\
8 15 35
```
``
`
1
2
/\
5 20
/\/\
2 8 15 35
```
``
`
1
2
/\
5 20
/\/\
2 8 15 35
\
4
0
```
``
`
1
2
/\
5 20
/\/\
2 8 15 35
/\\
14
40
```
**After balancing**:
``
`
1
2
/\
5 20
/\/\
2 8 15 35
/\/\
14 24 40
```
```
12
/\
5 20
/\/\
2 8 15 35
/\/\
14 24 40
\
2
7
```
``
`
1
2
/\
5 20
/\/\
2 8 15 35
/\/\
14 24 40
\\
27 45
```
``
`
1
2
/\
5 20
/\/\
2 8 15 35
/\/\
14 24 40
\\
27 45
\
5
0
```
``
`
1
2
/\
5 20
/\/\
2 8 15 35
\/\/\
3 14 24 40
\\
27 45
\
5
0
```
**Step 15: Insert 4**
- 4 becomes the right child of 3. No balancing is needed.
``
`
1
2
/\
5 20
/\/\
2 8 15 35
\/\/\
3 14 24 40
\\\
4 27 45
\
5
0
```
**Delete 2**:
- Node 2 is removed. Its child 3 becomes the left child of 5. No balancing is needed.
``
`
1
2
/\
5 20
/\/\
3 8 15 35
\/\/\
4 14 24 40
\\
27 45
\
5
0
```
**Delete 4**:
- Node 4 is removed. No further action is needed.
``
`
1
2
/\
5 20
/\/\
3 8 15 35
/\/\
14 24 40
\\
27 45
\
5
0
```
**Delete 5**:
- Node 5 is removed. Its right child 8 becomes the new left child of 12.
```
12
/\
8 20
//\
3 15 35
/\/\
14 24 40
\\
27 45
\
5
0
```
**Delete 12**:
- Node 12 is removed. Node 14 (in-order successor of 12) replaces 12, and the tree is rebalanced.
**Final Tree**:
``
`
1
4
/\
8 20
//\
3 15 35
\/\
24
40
\\
27 45
\
5
0
```
Q8. Define a B-tree and its properties. Create a B-tree of order-5, if the data items
are inserted into an empty B-tree in the following sequence:
12, 5, 15, 20, 60, 45, 35, 40, 25, 8, 7, 55, 50, 66, 65, 80
Further, delete the items 5, 12, 8, and 20 from
the B-tree. Ans:-
### Definition of a B-tree:
A **B-tree** is a self-balancing tree data structure that maintains sorted data and allows for
efficient insertion, deletion, and search operations. It is commonly used in databases and file
systems where data is read and written in large blocks.
We will build the B-tree by inserting the following sequence of keys into an empty B-tree:
```
12, 5, 15, 20, 60, 45, 35, 40, 25, 8, 7, 55, 50, 66, 65, 80
```
```
[ 12 ]
```
```
[ 5, 12 ]
```
```
[ 5, 12, 15 ]
```
```
[ 5, 12, 15, 20 ]
```
```
[ 15 ]
/\
[ 5, 12 ] [ 20, 60 ]
```
```
[ 15 ]
/\
[ 5, 12 ] [ 20, 45, 60 ]
```
```
[ 15 ]
/\
[ 5, 12 ] [ 20, 35, 45, 60 ]
```
```
[ 15, 45 ]
/|\
[ 5, 12 ] [ 20, 35 ] [ 60 ]
```
```
[ 15, 45 ]
/|\
[ 5, 12 ] [ 20, 25, 35 ] [ 60 ]
```
```
[ 15, 45 ]
/|\
[ 5, 8, 12 ] [ 20, 25, 35 ] [ 60 ]
```
```
[ 15, 45 ]
/|\
[ 5, 7, 8, 12 ] [ 20, 25, 35 ] [ 60 ]
```
```
[ 15, 45 ]
/|\
[ 5, 7, 8, 12 ] [ 20, 25, 35 ] [ 55, 60 ]
```
```
[ 15, 45 ]
/|\
[ 5, 7, 8, 12 ] [ 20, 25, 35 ] [ 50, 55, 60 ]
```
```
[ 15, 45, 60 ]
/||\
[ 5, 7, 8, 12 ] [ 20, 25, 35 ] [ 50, 55 ] [ 65, 66 ]
```
```
[ 15, 45, 60 ]
/||\
[ 5, 7, 8, 12 ] [ 20, 25, 35 ] [ 50, 55 ] [ 65, 66, 80 ]
```
```
[ 15, 45, 60 ]
/||\
[ 7, 8, 12 ] [ 20, 25, 35 ] [ 50, 55 ] [ 65, 66, 80 ]
```
```
[ 15, 45, 60 ]
/||\
[ 7, 8 ] [ 20, 25, 35 ] [ 50, 55 ] [ 65, 66, 80 ]
```
```
[ 15, 45, 60 ]
/||\
[ 7 ] [ 20, 25, 35 ] [ 50, 55 ] [ 65, 66, 80 ]
```
```
[ 15, 45, 60 ]
/||\
[ 7 ] [ 25, 35 ] [ 50, 55 ] [ 65, 66, 80 ]
```
```
[ 15, 45, 60 ]
/||\
[ 7 ] [ 25, 35 ] [ 50, 55 ] [ 65, 66, 80 ]
```
This is the final B-tree after the insertions and deletions.
Q9. Apply Dijkstra’s algorithm to find the shortest path from the vertex ‘S’ to all
other vertices for the following graph:
Ans:-
In order to apply **Dijkstra’s algorithm** to find the shortest path from vertex **S** to all other
vertices in a given graph, you will need the following steps:
5. **Repeat**:
- Repeat steps 2 to 4 until all vertices are visited.
6. **Output**:
- Once all nodes have been visited, the shortest path to each vertex from the source will
Let’s assume you have a graph with vertices **S, A, B, C, D, E**, and the following weighted
edges:
```
S --(4)--> A
S --(1)--> B
A --(3)--> C
A --(1)--> D
B --(2)--> A
B --(5)--> D
C --(6)--> E
D --(1)--> C
D --(4)--> E
```
1. **Initialization**:
- Distance from **S** to itself = 0.
- Distances from **S** to all other vertices = ∞.
```
Distance(S) =
0 Distance(A)
=∞
Distance(B) =
∞ Distance(C)
=∞
Distance(D) =
∞ Distance(E)
=∞
```
```
Distance(S) = 0
Distance(A) = 4
(via S) Distance(B)
= 1 (via S)
Distance(C) = ∞
Distance(D) = ∞
Distance(E) = ∞
```
```
Distance(S) = 0
Distance(A) = 3
(via B) Distance(B)
= 1 Distance(C) =
∞ Distance(D) = 6
(via B) Distance(E)
=∞
```
```
Distance(S) = 0
Distance(A) = 3
Distance(B) = 1
Distance(C) = 6
(via A) Distance(D)
= 4 (via A)
Distance(E) = ∞
```
5. **Choose Vertex D** (smallest distance = 4):
- From **D**, we can go to **C** with cost 1 (total = 4 + 1 = 5) and to **E** with cost 4 (total =
4 + 4 = 8).
- Update distances for **C** and **E**.
```
Distance(S) = 0
Distance(A) = 3
Distance(B) = 1
Distance(C) = 5
(via D) Distance(D)
= 4 Distance(E) =
8 (via D)
```
```
Distance(S) = 0
Distance(A) = 3
Distance(B) = 1
Distance(C) = 5
Distance(D) = 4
Distance(E) = 8
```
```
Distance(S) = 0
Distance(A) = 3
Distance(B) = 1
Distance(C) = 5
Distance(D) = 4
Distance(E) = 8
```
Q10. Apply Prim’s Algorithm to find the minimum spanning tree for the
these steps: ### Step 1: Start with any node. Let's start with **node 1**.
- **Node 1** has the following edges:
- 1 - 2: weight 8
- 1 - 7: weight 4
The smallest edge is **1 - 7** with weight **4**, so we add this edge
to the MST. ### Step 2: Include **node 7** in the MST. Now the
The smallest edge is **7 - 6** with weight **7**, so we add this edge
to the MST. ### Step 3: Include **node 6** in the MST. Now the
The smallest edge is **6 - 5** with weight **2**, so we add this edge
to the MST. ### Step 4: Include **node 5** in the MST. Now the
The smallest edge is **5 - 4** with weight **10**, so we add this edge
to the MST. ### Step 5: Include **node 4** in the MST. Now the
### Step 6: Include **node 3** in the MST. Now the available edges are:
- 3 - 2: weight 7
### Step 7: Include **node 2** in the MST. Now the available edges are:
- 2 - 1: weight 8 (already included)
So, the minimum spanning tree includes the edges with the weights **4, 7, 2, 10, 9, and 7**,
and the total weight is **39**.
Q11. Apply Insertion and Selection sorting algorithms to sort the following list of
items. So, all the intermediate steps. Also, analyze their best, worst and average
case time complexity.
12, 5, 2, 15, 25, 30, 45, 8, 17, 50, 3, 7
Ans:-
### Insertion Sort
**List to be sorted:**
`12, 5, 2, 15, 25, 30, 45, 8, 17, 50, 3, 7`
1. **Initial List**:
`12, 5, 2, 15, 25, 30, 45, 8, 17, 50, 3, 7`
2. **Pass 1 (i = 1)**:
Compare `5` with `12`, shift `12` to the right, and insert `5` at
the beginning. List: `5, 12, 2, 15, 25, 30, 45, 8, 17, 50, 3, 7`
3. **Pass 2 (i = 2)**:
Compare `2` with `12` and `5`, shift both to the right,
and insert `2`. List: `2, 5, 12, 15, 25, 30, 45, 8, 17, 50, 3,
7`
4. **Pass 3 (i = 3)**:
`15` is already in the correct
position. List: `2, 5, 12, 15, 25, 30,
45, 8, 17, 50, 3, 7`
5. **Pass 4 (i = 4)**:
`25` is already in the correct
position. List: `2, 5, 12, 15, 25, 30,
45, 8, 17, 50, 3, 7`
6. **Pass 5 (i = 5)**:
`30` is already in the correct
position. List: `2, 5, 12, 15, 25, 30,
45, 8, 17, 50, 3, 7`
7. **Pass 6 (i = 6)**:
`45` is already in the correct
position. List: `2, 5, 12, 15, 25, 30,
45, 8, 17, 50, 3, 7`
8. **Pass 7 (i = 7)**:
Compare `8` with `45, 30, 25, 15, 12`, shift them to the right,
and insert `8`. List: `2, 5, 8, 12, 15, 25, 30, 45, 17, 50, 3, 7`
9. **Pass 8 (i = 8)**:
Compare `17` with `45, 30, 25`, shift them to the right, and
insert `17`. List: `2, 5, 8, 12, 15, 17, 25, 30, 45, 50, 3, 7`
1. **Initial List**:
`12, 5, 2, 15, 25, 30, 45, 8, 17, 50, 3, 7`
2. **Pass 1**:
Find the smallest element (`2`) and swap with the first
element (`12`). List: `2, 5, 12, 15, 25, 30, 45, 8, 17, 50, 3, 7`
3. **Pass 2**:
Find the next smallest element (`3`) and swap with the second
element (`5`). List: `2, 3, 12, 15, 25, 30, 45, 8, 17, 50, 5, 7`
4. **Pass 3**:
Find the next smallest element (`5`) and swap with the third
element (`12`). List: `2, 3, 5, 15, 25, 30, 45, 8, 17, 50, 12, 7`
5. **Pass 4**:
Find the next smallest element (`7`) and swap with the fourth
element (`15`). List: `2, 3, 5, 7, 25, 30, 45, 8, 17, 50, 12, 15`
6. **Pass 5**:
Find the next smallest element (`8`) and swap with the fifth
element (`25`). List: `2, 3, 5, 7, 8, 30, 45, 25, 17, 50, 12, 15`
7. **Pass 6**:
Find the next smallest element (`12`) and swap with the sixth
element (`30`). List: `2, 3, 5, 7, 8, 12, 45, 25, 17, 50, 30, 15`
8. **Pass 7**:
Find the next smallest element (`15`) and swap with the seventh
element (`45`). List: `2, 3, 5, 7, 8, 12, 15, 25, 17, 50, 30, 45`
9. **Pass 8**:
Find the next smallest element (`17`) and swap with the eighth
element (`25`). List: `2, 3, 5, 7, 8, 12, 15, 17, 25, 50, 30, 45`
- **Insertion Sort:**
- **Best Case (already sorted)**: O(n)
- **Worst Case (reverse order)**: O(n²)
- **Average Case**: O(n²)
- **Selection Sort:**
- **Best Case**: O(n²)
- **Worst Case**: O(n²)
- **Average Case**: O(n²)
**Conclusion**: Insertion sort performs better than selection sort in the best-case scenario
when the list is already sorted, with a time complexity of O(n). However, in most other cases,
both algorithms have a time complexity of O(n²).
Q12. What is a heap tree? Create a max heap tree for the following list of items
inserted in the order. Also, explain the heap sort with the help of thus created
heap tree.
10, 20, 5, 25, 30, 18, 3, 70, 55, 45, 12, 24
Ans:-
### What is a Heap Tree?
A **heap tree** is a special binary tree that satisfies the **heap property**:
- In a **max heap**, for each node, the value of the parent is greater than or equal to the values
of its children.
- In a **min heap**, for each node, the value of the parent is less than or equal to the values of
its children.
A heap is usually implemented as a binary heap, which is a complete binary tree where every
level, except possibly the last, is fully filled, and all nodes are as far left as possible.
is:
`10, 20, 5, 25, 30, 18, 3, 70, 55, 45, 12, 24`
We will insert these elements one by one and maintain the max
1. **Insert 10**:
Heap: `[10]`
2. **Insert 20**:
Swap 20 with 10 to maintain the max heap
property. Heap: `[20, 10]`
3. **Insert 5**:
Heap: `[20, 10, 5]`
4. **Insert 25**:
Insert 25 as a child of 10, then swap 25 with 20 to maintain the heap
property. Heap: `[25, 20, 5, 10]`
5. **Insert 30**:
Insert 30 as a child of 20, then swap 30 with 25.
Heap: `[30, 25, 5, 10, 20]`
6. **Insert 18**:
Heap: `[30, 25, 18, 10, 20, 5]`
7. **Insert 3**:
Heap: `[30, 25, 18, 10, 20, 5, 3]`
8. **Insert 70**:
Insert 70, swap with 25, then with 30 to maintain the heap
property. Heap: `[70, 30, 18, 25, 20, 5, 3, 10]`
9. **Insert 55**:
Insert 55, swap with 25, then with 30.
Heap: `[70, 55, 18, 30, 20, 5, 3, 10, 25]`
Heap sort uses the heap data structure to sort elements. The steps are:
1. **Build a Max Heap**: Arrange the elements into a max heap, as shown above.
2. **Extract Max Element**: The largest element (root) is at the top of the heap. Swap it with
the last element in the heap and reduce the heap size by 1. Heapify the remaining heap.
3. **Heapify**: After each extraction, restore the heap property by reheapifying the root to
maintain the max heap structure.
4. **Repeat**: Continue this process of extracting the max element and heapifying until the
heap is empty. #### Example of Heap Sort Using the Above Max Heap:
1. **Initial Heap**:
`[70, 55, 18, 45, 20, 24, 3, 10, 25, 30, 12, 5]`
3. **Extract 55**:
Swap 55 with 12, reduce heap size, and
heapify: Heap after swap: `[12, 45, 18, 30,
20, 24, 3, 10, 25, 5]`
Heapify: `[45, 30, 18, 25, 20, 24, 3, 10, 12, 5]`
4. **Extract 45**:
Swap 45 with 5, reduce heap size, and
heapify: Heap after swap: `[5, 30, 18, 25,
20, 24, 3, 10, 12]`
Heapify: `[30, 25, 18, 12, 20, 24, 3, 10, 5]`
5. **Extract 30**:
Swap 30 with 5, reduce heap size, and
heapify: Heap after swap: `[5, 25, 18,
12, 20, 24, 3, 10]`
Heapify: `[25, 20, 18, 12, 5, 24, 3, 10]`
6. **Extract 25**:
Swap 25 with 10, reduce heap size, and heapify:
Heap after swap: `[10, 20, 18, 12, 5, 24, 3]`
Heapify: `[20, 12, 18, 10, 5, 24, 3]`
7. **Extract 20**:
Swap 20 with 3, reduce heap size, and
heapify: Heap after swap: `[3, 12, 18,
10, 5, 24]`
Heapify: `[18, 12, 3, 10, 5, 24]`
8. **Extract 18**:
Swap 18 with 24, reduce heap size, and
heapify: Heap after swap: `[24, 12, 3, 10,
5]`
Heapify: `[24, 12, 3, 10, 5]`
9. **Extract 24**:
Swap 24 with 5, reduce heap size, and
heapify: Heap after swap: `[5, 12, 3,
10]`
Heapify: `[12, 10, 3, 5]`
10.**Extract 12**:
Swap 12 with 5, reduce heap size, and
heapify: Heap after swap: `[5, 10, 3]`
Heapify: `[10, 5, 3]`
11.**Extract 10**:
Swap 10 with 3, reduce heap size, and
heapify: Heap after swap: `[3, 5]`
Heapify: `[5, 3]`
12.**Extract 5**:
Swap 5 with 3, reduce heap size, and
heapify: Heap after swap: `[3]`
13.**Extract 3**:
Heap is empty.
**Sorted List**:
`[3, 5, 10, 12, 18, 20, 24, 25, 30, 45, 55, 70]`
```c
#include
return 0;
}
```
### Explanation:
1. **`merge` function**:
- It takes three arguments: the array, the left index, and the right index. It merges two subarrays
(from `left` to
`mid` and from `mid + 1` to `right`) into a single sorted array.
- This function compares elements from two temporary arrays `L[]` and `R[]` and merges them
into the original array `arr[]`.
2. **`mergeSort` function**:
- This function recursively splits the array into two halves, sorts each half, and merges them
using the `merge` function. It divides the array until each subarray has only one element
(which is trivially sorted).
3. **`printArray` function**:
- This function prints the array elements.
4. **Main function**:
- The `main` function defines an array, calls the `mergeSort` function to sort the array, and
prints the sorted array.
Q14. What is Splay tree? Explain the Zig zag and Zag zig rotations in Splay tree with
the help of a suitable example.
Ans:-
### What is a Splay Tree?
A **Splay Tree** is a type of **self-adjusting binary search tree** where recently accessed
elements are moved to the root through a process called **splaying**. This helps to keep the
frequently accessed nodes near the top of the tree, improving the average access time for
these nodes.
Key operations like insertion, deletion, and search are followed by a splay operation, where the
accessed node
is moved to the root of the tree through a series of tree
The tree adjusts itself by performing a series of rotations (either **Zig**, **Zig-Zag**, **Zig-
Zig**, etc.) to bring the accessed node to the root. This process helps improve the time
complexity for future operations on recently accessed nodes.
---
occurs when:
- The node is a **right child** of its parent, and the parent is a **left child** of the grandparent.
#### Example:
Consider the following tree:
``
`
2
0
/
1
0
\
1
5
```
We want to splay node 15 (the right child of 10, and 10 is the left child of 20). This requires a
Zig-Zag (left- right) rotation.
---
occurs when:
- The node is a **left child** of its parent, and the parent is a **right child** of the grandparent.
#### Example:
Consider the following tree:
``
`
2
0
\
3
0
/
2
5
```
We want to splay node 25 (the left child of 30, and 30 is the right child of 20). This requires a
Zag-Zig (right- left) rotation.
### Summary
- **Zig-Zag** occurs when the node is a **right child** of its parent, and the parent is a
**left child** of its grandparent.
- **Zag-Zig** occurs when the node is a **left child** of its parent, and the parent is a
**right child** of its grandparent.
These rotations help maintain the balance of the tree by moving frequently accessed nodes
closer to the root,
thus optimizing future operations.
Q15. What is Red-Black tree? Explain insertion and deletion operations in a Red-
Black tree with the help of a suitable example.
Ans:-
### What is a Red-Black Tree?
A **Red-Black Tree** is a type of **self-balancing binary search tree** where each node stores
an extra bit representing "color" (either red or black). Red-Black Trees are used to ensure the
tree remains balanced after insertion or deletion operations, guaranteeing efficient search,
insertion, and deletion operations with a time complexity of **O(log n)**.
These properties ensure that the tree remains approximately balanced, preventing it from
becoming skewed like a regular binary search tree.
---
When inserting a new node into a Red-Black Tree, the following steps are followed to maintain
the Red-Black properties:
1. **Insert the node** like a regular binary search tree (BST) node. Initially, color the new node
**red**.
2. **Fix any Red-Black Tree property violations** caused by the insertion. These violations
can occur if the parent of the inserted node is also red (which violates the property of no
consecutive red nodes). There are three cases that need to be handled (usually with rotations
and color changes).
---
Let’s insert the following sequence of numbers into an empty Red-Black Tree:
`10, 20, 30, 15`
```
10 (black)
```
```
10 (black)
\
20 (red)
```
```
10 (black)
\
20 (red)
\
30 (red)
```
```
20 (black)
/\
10 (red) 30 (red)
```
```
20 (black)
/\
10 (red) 30 (red)
\
15 (red)
```
```
20 (black)
/\
15 (black) 30 (red)
/
10 (red)
```
---
1. **Remove the node** like you would in a regular binary search tree. If the node to be
deleted has two children, replace it with its in-order successor (the smallest node in the
right subtree) or its in-order predecessor (the largest node in the left subtree).
2. If the deleted node or the node that replaces it is **red**, the tree remains valid, and no
further fixes are required. If the node is **black**, it could violate the Red-Black properties,
and fixing is necessary.
---
```
20 (black)
/\
15 (black) 30 (red)
/
10 (red)
```
```
20 (black)
/\
15 (black) 30 (red)
```
---
```
20 (black)
\
30 (red)
```
```
20 (black)
\
30 (black)
```
The tree is now balanced and satisfies the Red-Black Tree properties.
---
- **Insertion**: Always insert a new node as **red**. Use rotations and recoloring to fix violations
if necessary.
- **Deletion**: If a black node is deleted, fix violations using recoloring and rotations to
maintain the tree's balance and properties.
These complexities ensure that Red-Black Trees are efficient for dynamic sets where insertions
and deletions occur frequently.
Organization. Ans:-
### Direct File Organization
**Direct File Organization**, also known as **hashing file organization**, is a method of file
storage where records are directly accessed using a **hash function**. This method is
particularly useful when quick access to records is needed, without having to search through
large sets of data sequentially.
#### Characteristics:
1. **Hash Function**: A mathematical function is used to calculate the address or location
where the record should be stored. The key (or some part of the data) is passed through this
hash function to generate a unique location or address in the file system.
2. **Direct Access**: Once the hash function computes the location, the system directly
accesses the record in that location, eliminating the need to search through the file
sequentially.
3. **Collisions**: Two different records may have the same hash value, leading to a
**collision**. Various strategies such as **open addressing** or **chaining** are used to
handle collisions.
4. **Efficient for Random Access**: This method is very efficient when you need to frequently
retrieve or update data quickly. It is commonly used in databases where records are accessed
using a unique identifier (like student ID or account number).
#### Advantages:
- **Fast Access**: Since the hash function provides direct access to a record, there’s no need
to perform a sequential search, making it faster for retrieval.
- **Best for Unique Records**: Works best when accessing records using a unique key, such
as an account number or employee ID.
#### Disadvantages:
- **Collisions**: Collisions can occur when multiple records are assigned the same hash
value, leading to complexity in managing and retrieving those records.
- **Space**: Hashing can result in unused space (called **bucket overflow**), leading to
inefficient use of storage.
---
### Indexed Sequential File Organization
**Indexed Sequential File Organization** combines the benefits of **sequential access** with
**direct
access** using an **index**. This file organization method stores records sequentially but also
maintains an index that allows for quicker access to records without searching through the
entire file.
#### Characteristics:
1. **Sequential Storage**: The records are stored in a sequential order based on a key field
(such as customer ID or name). This allows for easy sequential access.
2. **Index Table**: Along with sequential storage, an index table is maintained. This table
contains key fields and pointers (addresses) to the corresponding record. The index allows for
faster access by providing direct pointers to specific data blocks.
4. **Direct and Sequential Access**: Indexed Sequential File Organization supports both
**sequential access** (for reading through records) and **direct access** (for quickly locating
specific records using the index).
#### Example:
If we have a file containing student records with fields like **Student ID** and **Name**, the
records might be stored in sequential order by **Student ID**. An index table is built using the
**Student ID** that points to the specific locations of these records.
When a record with **Student ID 1010** is searched, the index table is first checked to find
the block where this record is stored. This allows for faster access compared to searching
through the entire list of records sequentially.
#### Advantages:
- **Fast Access**: The index allows for fast direct access to records.
- **Sequential and Direct Access**: The method supports both sequential and direct
access to records, making it flexible.
- **Efficient for Large Files**: It is useful for large files where random access is required
frequently, but sequential access is also needed for processing large amounts of data.
#### Disadvantages:
- **Index Overhead**: Maintaining an index table requires extra space and memory, which adds
overhead.
- **Updating the Index**: When records are inserted or deleted, the index must be
updated, which adds complexity.
---
### Summary:
- **Direct File Organization** is efficient for random access using unique keys through
hashing but requires managing collisions.
- **Indexed Sequential File Organization** provides both sequential and direct access to data
using an index, making it suitable for large datasets where both types of access are needed.
However, maintaining the index adds complexity.