dsa file
dsa file
Department of
B.TECH CSE – AI & DS
Assessment
Date of Practical
S.
Attendance(1
Performance
No. Name of Practical
Total Marks
File Record
Faculty
Viva (10)
Lab
(10)
(10)
(40)
Sign.
0)
1. Write a program for binary search
method.
Aggregated Marks
Practical No. 1
Aim:
Objectives:
1. Show how binary search divides the search range into halves, significantly reducing the
number of comparisons.
2. Allow users to input a target element and provide the result of the search.
Key Points:
Time Complexity: Worst-case time complexity is O (log n)), making it much faster than
linear search for large datasets.
Flexibility: Can be extended to handle various data types or use recursion instead of
iteration.
Algorithm Mechanics: Divides the array into halves repeatedly and compares the middle
element with the target to decide which half to continue searching.
Algorithm:
BINARY (DATA,LB,UB,ITEM,LOC)
1. Set BEG =LB,END=UB,MID=INT(BEG+END)/2)
2. Repeat step 3 & 4 while BEG<=END and DATA(MID) ≠ITEM
3. If ITEM <DATA[MID],then:
Set END=MID-1
Else:
Set BEG=MID+1
Set MID=INT (BEG+END)/2
4. If DATA[MID]=ITEM, then:
Set LOC=MID
Else:
Set =LOC=NULL
5. Exit
Source Code:
#include <stdio.h>
if (arr[mid] == target)
return mid;
return -1;
}
int main() {
int arr[] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
int size = sizeof(arr) / sizeof(arr[0]);
int target;
if (result != -1)
printf("Element found at index %d\n", result);
else
printf("Element not found in the array.\n");
return 0;
}
Output:
Aim:
Objective:
1. Show how binary search divides the search range into halves, significantly reducing the
number of comparisons.
2. Allow users to input a target element and provide the result of the search.
Requirements:
Output:
Viva Questions:
Q1 : What is the time complexity of the binary search algorithm implemented in this
program?
Ans : The time complexity of the binary search algorithm is O(log n), where n is the size of
the array. This is because the search space is halved with each iteration of the loop,
reducing the number of comparisons logarithmically.
Q2 : What does the binarySearch() function return if the target element is found?
Ans : If the target element is found in the array, the binarySearch() function returns the
index of the element within the array.
Q4 : How does the program determine whether to search the left or right half of the array?
Ans : It compares the target with the middle element: if the target is smaller, it searches the
left half; if larger, it searches the right half.
Practical No. 2
Aim:
Objectives:
1. By implementing multiple sorting algorithms, the program helps reinforce the concepts
of algorithm design and complexity analysis.
2. Through the printArray function, the program shows the array before and after sorting,
making it easy to visualize the effect of each algorithm.
Algorithm:
A. For Insertion Sort:
INSERTION(A,N)
1. Set A[0] = –∞ [Initialize sentinel element]
2. Repeat step 3 to 5 for K = 2, 3, - - - - - - - , N
3. Set Temp = A[K] and PTR = K-1
4. Repeat while Temp < A[PTR]:
a) Set A[PTR + 1] = A[PTR]
b) Set PTR = PTR – 1
5. Set A[PTR + 1] = TEMP [End of step 2 loop]
6. Return
Key Points:
Space Complexity: All algorithms are in-place, requiring O(1) additional space.
Input and Output: The program uses a predefined array of integers, prints the unsorted
array, and displays the sorted results for each algorithm.
Sorting Order: All algorithms sort the array in ascending order..
Efficiency:All three algorithms have a worst-case time complexity of O(n²).
Source Code:
#include <stdio.h>
// Insertion Sort Function
void insertionSort(int arr[], int size) {
for (int i = 1; i < size; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
// Selection Sort Function
void selectionSort(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < size; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
// Bubble Sort Function
void bubbleSort(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// Function to print the array
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr1[] = {64, 25, 12, 22, 11};
int size = sizeof(arr1) / sizeof(arr1[0]);
printf("Original Array: ");
printArray(arr1, size);
// Insertion Sort
insertionSort(arr1, size);
printf("Array after Insertion Sort: ");
printArray(arr1, size);
// Reinitialize the array for other sorts
int arr2[] = {64, 25, 12, 22, 11};
// Selection Sort
selectionSort(arr2, size);
printf("Array after Selection Sort: ");
printArray(arr2, size);
// Reinitialize the array for other sorts
int arr3[] = {64, 25, 12, 22, 11};
// Bubble Sort
bubbleSort(arr3, size);
printf("Array after Bubble Sort: ");
printArray(arr3, size);
return 0;
}
Output:
Aim:
Objective:
1. By implementing multiple sorting algorithms, the program helps reinforce the concepts
of algorithm design and complexity analysis.
2. Through the printArray function, the program shows the array before and after sorting,
making it easy to visualize the effect of each algorithm.
Requirements:
Output:
Viva Questions:
Q1 : What is the purpose of the program?
Ans : The program demonstrates the implementation of three sorting algorithms: Insertion
Sort, Selection Sort, and Bubble Sort, to sort an array in ascending order
Q2 : What is the time complexity of each sorting algorithm in the worst case?
Ans : The worst-case time complexity of all three algorithms is O(n²).
Q4 : What happens if the array is already sorted before applying these algorithms?
Ans : Insertion Sort will run in O(n) time, as it makes minimal comparisons and no shifts.
Selection Sort and Bubble Sort will still run in O(n²), as they do not optimize for
sorted array
Practical No.3
Aim:
Algorithm:
STACK-EMPTY(S)
If top[S] = 0
return true
PUSH(S, x)
S[top[S]] <- x
POP(S)
if STACK-EMPTY(S)
return S[top[S] + 1]
Source Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int items[MAX];
int top;
} Stack;
s->top = -1;
if (isFull(s)) {
return;
s->items[++(s->top)] = value;
if (isEmpty(s)) {
return -1;
return s->items[(s->top)--];
if (isEmpty(s)) {
return -1;
return s->items[s->top];
if (isEmpty(s)) {
printf("Stack is empty!\n");
return;
printf("\n");
int main() {
Stack s;
initialize(&s);
while (1) {
printf("\nStack Operations:\n");
printf("1. Push\n");
printf("2. Pop\n");
printf("3. Peek\n");
printf("4. Display\n");
printf("5. Exit\n");
scanf("%d", &choice);
switch (choice) {
case 1:
scanf("%d", &value);
push(&s, value);
break;
case 2:
value = pop(&s);
if (value != -1)
break;
case 3:
value = peek(&s);
if (value != -1)
break;
case 4:
display(&s);
break;
case 5:
printf("Exiting program.\n");
exit(0);
default:
return 0;
Output:
Practical No. 4
Aim:
Procedure:
QUICK(A, N, Beg, End, LOC)
1. Set Left = Beg , Right = End, LOC = Beg
2. [Scan right to left]
a) Repeat while A[LOC] <= Right and LOC ≠ Right
Right = Right-1 [End of loop]
b) If LOC = Right, then : Return
c) If A[LOC] > A[Right] then:
i) Temp = A[LOC], A[LOC] = A[Right],
A[Right] = Temp
ii) Set LOC = Right
iii) Go to step 3
3. [Scan from left to right]
a) Repeat while A[Left] <= A[LOC] and Left ≠ LOC
Left = Left + 1 [End of loop]
b) If LOC = Left, then: Return
c) If A[Left] > A[LOC], then:
i)Temp = A[LOC], A[LOC] = A[Left],
A[Left] = Temp
ii) Set LOC = Left
iii) Go to step 2
Algorithm:
1. [Initialize] Top = Null
2. [Push boundary values of A onto stacks when A has 2 or more elements]
If N > 1, then TOP = TOP + 1, LOWER[1] = 1, UPPER[1] = N
3. Repeat step 4 to 7 while Top ≠ Null
4. [Pop sublist from stacks]
Set Beg = LOWER[TOP], End = UPPER[TOP] TOP = TOP – 1
5. Call QUICK(A, N, Beg, End, LOC)
6. [PUSH left sublist onto stacks when it has 2 or more elements]
If Beg < LOC-1 then:
#include <stdio.h>
*a = *b;
*b = temp;
if (arr[j] <= pivot) { // If current element is smaller than or equal to the pivot
i++;
swap(&arr[i], &arr[j]);
printf("\n");
int main() {
printArray(arr, size);
printArray(arr, size);
return 0;
Output:
Practical No.5
Aim:
[End of loop]
10. For I = low to high do
11. Set ar[I] = br[I]
12. Exit.
Source Code:
#include <stdio.h>
// Function to merge two subarrays
void merge(int arr[], int left, int mid, int right) {
int n1 = mid - left + 1; // Size of the left subarray
int n2 = right - mid; // Size of the right subarray
int L[n1], R[n2]; // Temporary arrays to hold the subarrays
// Copy data to temporary arrays
for (int i = 0; i < n1; i++)
L[i] = arr[left + i];
for (int j = 0; j < n2; j++)
R[j] = arr[mid + 1 + j];
// Merge the temporary arrays back into the original array
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
// Copy remaining elements of L[], if any
}
int main() {
int arr[] = {12, 11, 13, 5, 6, 7};
int size = sizeof(arr) / sizeof(arr[0]);
printf("Original array: ");
printArray(arr, size);
mergeSort(arr, 0, size - 1);
printf("Sorted array: ");
printArray(arr, size);
return 0;
}
Output:
Practical No.6
Aim:
Algorithm:
ENQUEUE(Q, x)
Q[tail[Q]] <- x
if tail[Q] = length[Q]
DEQUEUE(Q)
x <- Q[head[Q]]
if head[Q] = length[Q]
return x
Source Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 100 // Maximum size of the queue
int main() {
Queue q;
initialize(&q);
int choice, value;
while (1) {
printf("\nQueue Operations:\n");
printf("1. Enqueue\n");
printf("2. Dequeue\n");
printf("3. Peek\n");
printf("4. Display\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter the value to enqueue: ");
scanf("%d", &value);
enqueue(&q, value);
break;
case 2:
value = dequeue(&q);
if (value != -1)
printf("Dequeued %d from the queue.\n", value);
break;
case 3:
value = peek(&q);
if (value != -1)
printf("Front element is %d.\n", value);
break;
case 4:
display(&q);
break;
case 5:
printf("Exiting program.\n");
exit(0);
default:
printf("Invalid choice! Please try again.\n");
}
}
return 0;
}
Output:
Practical No.7
Aim:
Algorithm:
add_circular( item,queue,rear,front)
{ rear=(rear+1)mod n;
if (front == rear)
delete_circular (item,queue,rear,front)
{ if (front = = rear)
item=queue[front]; }
}
Source Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 5 // Maximum size of the circular queue
// Structure for Circular Queue
typedef struct {
int items[MAX];
int front, rear;
} CircularQueue;
// Function to initialize the circular queue
void initialize(CircularQueue *q) {
q->front = -1;
q->rear = -1;
}
// Function to check if the circular queue is empty
int isEmpty(CircularQueue *q) {
return q->front == -1;
}
// Function to check if the circular queue is full
int isFull(CircularQueue *q) {
return (q->rear + 1) % MAX == q->front;
}
// Function to enqueue (add) an element to the circular queue
void enqueue(CircularQueue *q, int value) {
if (isFull(q)) {
printf("Circular Queue Overflow! Unable to enqueue %d.\n", value);
return;
}
if (isEmpty(q)) {
q->front = 0;
}
q->rear = (q->rear + 1) % MAX;
q->items[q->rear] = value;
printf("Enqueued %d to the circular queue.\n", value);
}
int main() {
CircularQueue q;
initialize(&q);
int choice, value;
while (1) {
printf("\nCircular Queue Operations:\n");
printf("1. Enqueue\n");
printf("2. Dequeue\n");
printf("3. Peek\n");
printf("4. Display\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter the value to enqueue: ");
scanf("%d", &value);
enqueue(&q, value);
break;
case 2:
value = dequeue(&q);
if (value != -1)
printf("Dequeued %d from the circular queue.\n", value);
break;
case 3:
value = peek(&q);
if (value != -1)
printf("Front element is %d.\n", value);
break;
case 4:
display(&q);
break;
case 5:
printf("Exiting program.\n");
exit(0);
default:
printf("Invalid choice! Please try again.\n");
}
}
return 0;
}
Output:
Practical No. 8
Aim:
Write a program to implement Singly Linked List for the following operation: Create, Display,
Searching, Traversing, Deletion.
Procedure:
2. Every data object has two parts-a data part and a link part. Together they constitute a node.
6. Tree structures (branched link lists) are used to store data into disks.
Source Code:
#include <stdio.h>
#include <stdlib.h>
// Node structure for the singly linked list
typedef struct Node {
int data;
struct Node *next;
} Node;
// Function to create a new node
Node* createNode(int value) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
// Function to create a singly linked list
void create(Node **head, int value) {
Node *newNode = createNode(value);
if (*head == NULL) {
*head = newNode;
} else {
Node *temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
printf("Node with value %d created.\n", value);
}
// Function to display the linked list
void display(Node *head) {
if (head == NULL) {
printf("The list is empty.\n");
return;
}
printf("Linked List: ");
while (head != NULL) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}
deleteNode(&head, key);
break;
case 6:
printf("Exiting program.\n");
exit(0);
default:
printf("Invalid choice! Please try again.\n");
}
}
return 0;
}
Output:
Practical No. 9
Aim:
Write a program to implement Doubly Linked List for the following operation: Create, Display,
Inserting, Counting, Searching, Traversing and Deletion.
Procedure:
2. Every data object has two parts-a data part and a link part. Together they constitute node.
6. Tree structures (branched link lists) are used to store data into disks.
Source Code:
#include <stdio.h>
#include <stdlib.h>
// Node structure for doubly linked list
typedef struct Node {
int data;
struct Node *prev;
struct Node *next;
} Node;
// Function to create a new node
Node* createNode(int value) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
// Function to create a doubly linked list
void create(Node **head, int value) {
Node *newNode = createNode(value);
if (*head == NULL) {
*head = newNode;
} else {
Node *temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
printf("Node with value %d created.\n", value);
}
// Function to display the doubly linked list
void display(Node *head) {
if (head == NULL) {
printf("The list is empty.\n");
return;
}
printf("Doubly Linked List: ");
while (head != NULL) {
printf("%d <-> ", head->data);
head = head->next;
}
printf("NULL\n");
}
// Function to insert a node at the beginning
void insertAtBeginning(Node **head, int value) {
Node *newNode = createNode(value);
if (*head == NULL) {
*head = newNode;
} else {
newNode->next = *head;
(*head)->prev = newNode;
*head = newNode;
}
printf("Node with value %d inserted at the beginning.\n", value);
}
// Function to count the number of nodes in the doubly linked list
int count(Node *head) {
int count = 0;
while (head != NULL) {
count++;
head = head->next;
}
return count;
}
// Function to search for an element in the doubly linked list
void search(Node *head, int key) {
int position = 0;
while (head != NULL) {
if (head->data == key) {
printf("Element %d found at position %d.\n", key, position);
return;
}
head = head->next;
position++;
}
printf("Element %d not found in the list.\n", key);
}
// Function to traverse the doubly linked list
void traverse(Node *head) {
if (head == NULL) {
printf("The list is empty. No elements to traverse.\n");
return;
}
printf("Traversing the list: ");
while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
// Function to delete a node from the doubly linked list
void deleteNode(Node **head, int key) {
Node *temp = *head;
// If the list is empty
if (*head == NULL) {
printf("The list is empty. No nodes to delete.\n");
return;
}
int main() {
Node *head = NULL;
int choice, value, key;
while (1) {
printf("\nDoubly Linked List Operations:\n");
printf("1. Create Node\n");
printf("2. Display List\n");
printf("3. Insert at Beginning\n");
printf("4. Count Nodes\n");
printf("5. Search Element\n");
printf("6. Traverse List\n");
printf("7. Delete Node\n");
printf("8. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter value to create a node: ");
scanf("%d", &value);
create(&head, value);
break;
case 2:
display(head);
break;
case 3:
printf("Enter value to insert at the beginning: ");
scanf("%d", &value);
insertAtBeginning(&head, value);
break;
case 4:
printf("Total nodes: %d\n", count(head));
break;
case 5:
printf("Enter value to search: ");
scanf("%d", &key);
search(head, key);
break;
case 6:
traverse(head);
break;
case 7:
printf("Enter value to delete: ");
scanf("%d", &key);
deleteNode(&head, key);
break;
case 8:
printf("Exiting program.\n");
exit(0);
default:
printf("Invalid choice! Please try again.\n");
}
}
return 0;
}
Output:
Practical No. 10
Aim:
Write a program to implement Circular Linked List for the following operation: Create, Display,
Inserting, Counting, Searching, Traversing and Deletion.
Procedure:
Linked list is a data structure with the following specifics::
1. Data is dynamically added or removed.
2. Every data object has two parts-a data part and a link part. Together they constitute node.
3. The list can be traversed only through pointers.
4. Every node is an important constituent of the data.
5. The end of the data is always a leaf end.
6. Tree structures (branched link lists) are used to store data into disks.
Source Code:
#include <stdio.h>
#include <stdlib.h>
// Node structure for Circular Linked List
typedef struct Node {
int data;
struct Node *next;
} Node;
// Function to create a new node
Node* createNode(int value) {
Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = NULL;
return newNode;
}
printf("(back to head)\n");
}
// Function to insert a node at the beginning
void insertAtBeginning(Node **head, int value) {
Node *newNode = createNode(value);
if (*head == NULL) {
*head = newNode;
newNode->next = *head;
} else {
Node *temp = *head;
while (temp->next != *head) {
temp = temp->next;
}
newNode->next = *head;
*head = newNode;
temp->next = *head;
}
printf("Node with value %d inserted at the beginning.\n", value);
}
// Function to insert a node at the end
void insertAtEnd(Node **head, int value) {
Node *newNode = createNode(value);
if (*head == NULL) {
*head = newNode;
newNode->next = *head;
} else {
Node *temp = *head;
while (temp->next != *head) {
temp = temp->next;
}
temp->next = newNode;
newNode->next = *head;
}
printf("Node with value %d inserted at the end.\n", value);
}
// Function to count the number of nodes in the circular linked list
int count(Node *head) {
int count = 0;
if (head != NULL) {
Node *temp = head;
do {
count++;
temp = temp->next;
} while (temp != head);
}
return count;
}
// Function to search for an element in the circular linked list
void search(Node *head, int key) {
int position = 0;
if (head != NULL) {
Node *temp = head;
do {
if (temp->data == key) {
printf("Element %d found at position %d.\n", key, position);
return;
}
temp = temp->next;
position++;
} while (temp != head);
}
printf("Element %d not found in the list.\n", key);
}
// Function to traverse the list
void traverse(Node *head) {
if (head == NULL) {
printf("The list is empty. No elements to traverse.\n");
return;
}
Node *temp = head;
printf("Traversing the list: ");
do {
printf("%d ", temp->data);
temp = temp->next;
} while (temp != head);
printf("\n");
}
// Function to delete a node from the circular linked list
void deleteNode(Node **head, int key) {
if (*head == NULL) {
printf("The list is empty. No nodes to delete.\n");
return;
}
if (temp->data != key) {
printf("Element %d not found in the list.\n", key);
return;
}
// Unlink the node and free memory
prev->next = temp->next;
free(temp);
printf("Node with value %d deleted from the list.\n", key);
}
int main() {
Node *head = NULL;
int choice, value, key;
while (1) {
printf("\nCircular Linked List Operations:\n");
printf("1. Create Node\n");
printf("2. Display List\n");
printf("3. Insert at Beginning\n");
printf("4. Insert at End\n");
printf("5. Count Nodes\n");
printf("6. Search Element\n");
printf("7. Traverse List\n");
printf("8. Delete Node\n");
printf("9. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter value to create a node: ");
scanf("%d", &value);
create(&head, value);
break;
case 2:
display(head);
break;
case 3:
printf("Enter value to insert at the beginning: ");
scanf("%d", &value);
insertAtBeginning(&head, value);
break;
case 4:
printf("Enter value to insert at the end: ");
scanf("%d", &value);
insertAtEnd(&head, value);
break;
case 5:
printf("Total nodes: %d\n", count(head));
break;
case 6:
printf("Enter value to search: ");
scanf("%d", &key);
search(head, key);
break;
case 7:
traverse(head);
break;
case 8:
Practical No. 11
Aim:
Write a program to implement Insertion, Deletion and Traversing in B Tree.
Algorithm:
Insertion
Deletion
- If the child preceding the key has at least `t` keys, replace the key with its predecessor and
recursively delete the predecessor.
- If the succeeding child has at least `t` keys, replace the key with its successor and recursively
delete the successor.
- If both the child and its succeeding sibling have `t-1` keys, merge them.
- Determine the child that must contain the key, and recursively delete it.
- Borrow a key from its preceding or succeeding sibling if the sibling has at least `t` keys.
- Merge the node with one of its siblings if both siblings have only `t-1` keys.
4. Repeat the process until the key is deleted or determined not to be in the tree.
Traversing
int i = node->n - 1;
if (node->leaf) {
while (i >= 0 && node->keys[i] > key) {
node->keys[i + 1] = node->keys[i];
i--;
}
node->keys[i + 1] = key;
node->n++;
} else {
while (i >= 0 && node->keys[i] > key)
i--;
i++;
if (node->children[i]->n == 2 * node->t - 1) {
splitChild(node, i);
if (node->keys[i] < key)
i++;
}
insertNonFull(node->children[i], key);
}
}
// Function to split a child of a node
void splitChild(BTreeNode *parent, int i) {
int t = parent->t;
BTreeNode *y = parent->children[i];
BTreeNode *z = createNode(t, y->leaf);
int j;
z->n = t - 1;
merge(x, i - 1);
}
}
// Function to borrow a key from the previous sibling
void borrowFromPrev(BTreeNode *x, int i) {
BTreeNode *child = x->children[i];
BTreeNode *sibling = x->children[i - 1];
for (int j = child->n - 1; j >= 0; j--)
child->keys[j + 1] = child->keys[j];
if (!child->leaf) {
for (int j = child->n; j >= 0; j--)
child->children[j + 1] = child->children[j];
}
child->keys[0] = x->keys[i - 1];
if (!x->leaf)
child->children[0] = sibling->children[sibling->n];
x->keys[i - 1] = sibling->keys[sibling->n - 1];
child->n++;
sibling->n--;
}
// Function to borrow a key from the next sibling
void borrowFromNext(BTreeNode *x, int i) {
BTreeNode *child = x->children[i];
BTreeNode *sibling = x->children[i + 1];
child->keys[child->n] = x->keys[i];
if (!(child->leaf))
child->children[child->n + 1] = sibling->children[0];
x->keys[i] = sibling->keys[0];
}
Output: