0% found this document useful (0 votes)
2 views21 pages

Min-Max Heap Operations in C & Python

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views21 pages

Min-Max Heap Operations in C & Python

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Advanced Data Structures Lab Programs int gp = parent(parent(i));

if ((gp >= 0) && (h->heap[gp] > h->heap[i])) {


swap(&h->heap[gp], &h->heap[i]);
Lab – 04 bubble_Up_Max(h, gp);
Write a program to perform the following operations: }
}
a) Insert an element into a Min-Max heap void bubble_Up(MinMaxHeap *h, int i) {
b) Delete an element from a Min-Max heap if (i == 0) return;
c) Search for a key element in a Min-Max heap int p = parent(i);
int lvl = level(i);
if (lvl % 2 == 0) { // even level → MIN level
if (h->heap[p] < h->heap[i]) {
In C Language : swap(&h->heap[p], &h->heap[i]);
#include <stdio.h> bubble_Up(h, p);
#include <stdlib.h> } else {
#include <math.h> bubble_Up_Max(h, i);
#include <limits.h> }
#define MAX_SIZE 100 } else { // odd level → MAX level
typedef struct { if (h->heap[p] > h->heap[i]) {
int heap[MAX_SIZE]; swap(&h->heap[p], &h->heap[i]);
int size; bubble_Up(h, p);
} MinMaxHeap; } else {
void initialize_heap(MinMaxHeap *h) { bubble_Up_Min(h, i);
h->size = 0; }
} }
int parent(int i) { return (i - 1) / 2; } }
int left_child(int i) { return 2 * i + 1; } void insert(MinMaxHeap *h, int value) {
int right_child(int i) { return 2 * i + 2; } if (h->size == MAX_SIZE) return;
int level(int i) { return (int)log2(i + 1); } h->heap[h->size] = value;
void swap(int *a, int *b) { bubble_Up(h, h->size);
int temp = *a; h->size++;
*a = *b; }
*b = temp; void display(MinMaxHeap *h) {
} printf("Heap = [");
void bubble_Up_Min(MinMaxHeap *h, int i) { for (int i = 0; i < h->size; i++) {
int gp = parent(parent(i)); printf("%d", h->heap[i]);
if ((gp >= 0) && (h->heap[gp] < h->heap[i])) { if (i < h->size - 1) printf(", ");
swap(&h->heap[gp], &h->heap[i]); }
bubble_Up_Min(h, gp); printf("]\n");
} }
} int find_Smallest_Desendand(MinMaxHeap *h, int i) {
void bubble_Up_Max(MinMaxHeap *h, int i) { int candidates[6] = {
left_child(i), right_child(i), }
void bubble_Down_Min(MinMaxHeap *h, int i) {
left_child(left_child(i)), right_child(left_child(i)), int m = find_Smallest_Desendand(h, i);
if (m == -1) return;
left_child(right_child(i)), right_child(right_child(i)) if (h->heap[m] < h->heap[i]) {
}; swap(&h->heap[m], &h->heap[i]);
int minVal = INT_MAX, minIdx = -1; int p = parent(m);
for (int j = 0; j < 6; j++) { if (p >= 0 && h->heap[m] > h->heap[p]) swap(&h-
int idx = candidates[j]; >heap[m], &h->heap[p]);
if (idx < h->size && h->heap[idx] < minVal) { bubble_Down_Min(h, m);
minVal = h->heap[idx]; }
minIdx = idx; }
} void bubble_Down_Max(MinMaxHeap *h, int i) {
} int m = find_Largest_Desendand(h, i);
return minIdx; if (m == -1) return;
} if (h->heap[m] > h->heap[i]) {
int find_Largest_Desendand(MinMaxHeap *h, int i) { swap(&h->heap[m], &h->heap[i]);
int candidates[6] = { int p = parent(m);
left_child(i), right_child(i), if (p >= 0 && h->heap[m] < h->heap[p]) swap(&h-
>heap[m], &h->heap[p]);
left_child(left_child(i)), right_child(left_child(i)), bubble_Down_Max(h, m);
}
left_child(right_child(i)), right_child(right_child(i)) }
}; int delete_Min(MinMaxHeap *h) {
int maxVal = INT_MIN, maxIdx = -1; if (h->size == 0) return INT_MIN;
for (int j = 0; j < 6; j++) { int minVal = h->heap[0];
int idx = candidates[j]; h->heap[0] = h->heap[h->size - 1];
if (idx < h->size && h->heap[idx] > maxVal) { h->size--;
maxVal = h->heap[idx]; if (h->size > 0) bubble_Down(h, 0);
maxIdx = idx; return minVal;
} }
} int delete_Max(MinMaxHeap *h) {
return maxIdx; if (h->size == 0) return INT_MAX;
} if (h->size == 1) {
void bubble_Down_Min(MinMaxHeap *h, int i); int val = h->heap[0];
void bubble_Down_Max(MinMaxHeap *h, int i); h->size--;
void bubble_Down(MinMaxHeap *h, int i) { return val;
int lvl = level(i); }
if (lvl % 2 == 0) int maxIdx = (h->size == 2 || h->heap[1] > h-
bubble_Down_Min(h, i); >heap[2]) ? 1 : 2;
else int maxVal = h->heap[maxIdx];
bubble_Down_Max(h, i); h->heap[maxIdx] = h->heap[h->size - 1];
h->size--; scanf("%d", &key);
if (h->size > maxIdx) bubble_Down(h, maxIdx); insert(&h, key);
return maxVal; display(&h);
} break;
int getMin(MinMaxHeap *h) { case 2:
return (h->size > 0) ? h->heap[0] : INT_MIN; printf("Minimum element: %d\
} n", getMin(&h));
int getMax(MinMaxHeap *h) { break;
if (h->size == 0) return INT_MIN; case 3:
if (h->size == 1) return h->heap[0]; printf("Maximum element: %d\
if (h->size == 2) return h->heap[1]; n", getMax(&h));
return (h->heap[1] > h->heap[2]) ? h->heap[1] : h- break;
>heap[2]; case 4:
} printf("Deleted Minimum: %d\
void search(MinMaxHeap *h, int key) { n", delete_Min(&h));
for (int i = 0; i < h->size; i++) { display(&h);
if (h->heap[i] == key) { break;
printf("Element found at index: %d\n", i); case 5:
return; printf("Deleted Maximum: %d\
} n", delete_Max(&h));
} display(&h);
printf("Element was not found\n"); break;
} case 6:
int main() { printf("Enter element to search: ");
MinMaxHeap h; scanf("%d", &key);
initialize_heap(&h); search(&h, key);
int choice, key, flag = 1; break;
while (flag) { case 7:
printf("\n\nChoose the Operation:\n"); display(&h);
printf("1. Insertion\n"); break;
printf("2. Get Minimum\n"); case 0:
printf("3. Get Maximum\n"); flag = 0;
printf("4. Delete Minimum\n"); printf("Exiting...\n");
printf("5. Delete Maximum\n"); break;
printf("6. Search\n"); default:
printf("7. Display\n"); printf("Invalid choice. Try again.\n");
printf("0. Exit\n"); }
printf("Enter your choice: "); }
scanf("%d", &choice);
switch (choice) { return 0;
case 1: }
printf("Enter element to insert: ");
return 2 * i + 1
def right(self, i):
"""Return right child index of node i."""
In Python Language : return 2 * i + 2
def level(self, i):
"""
"""Return level (depth) of index i in the
---------------------------------------------------------
heap."""
Min-Max Heap Implementation in Python
return int(math.log2(i + 1))
---------------------------------------------------------
def swap(self, i, j):
A Min-Max Heap is a complete binary tree that allows:
"""Swap two elements in the heap."""
- O(1) access to both the minimum and maximum elements.
[Link][i], [Link][j]
- O(log n) insertion and deletion.
= [Link][j], [Link][i]
This implementation supports:
@property
1. insert(value)
def size(self):
2. get_min()
"""Return current heap size."""
3. get_max()
return len([Link])
4. delete_min()
# ---------------------------------------------------
5. delete_max()
# Bubble-up operations (restore heap after insertion)
6. search(value)
# ---------------------------------------------------
7. display()
def bubble_up_min(self, i):
Author : Pravalika Srinivas
"""Bubble up on even (min) levels."""
Language : Python
grandparent
---------------------------------------------------------
= [Link]([Link](i)) if [Link](i) is not Non
"""
e else None
import math
if grandparent is not None and [Link][i]
< [Link][grandparent]:
class MinMaxHeap: [Link](i, grandparent)
"""Class implementing a Min-Max Heap data self.bubble_up_min(grandparent)
structure.""" def bubble_up_max(self, i):
def __init__(self, capacity=100): """Bubble up on odd (max) levels."""
"""Initialize an empty heap with a given grandparent
capacity.""" = [Link]([Link](i)) if [Link](i) is not Non
[Link] = [] e else None
[Link] = capacity if grandparent is not None and [Link][i]
# --------------------------------------------------- > [Link][grandparent]:
# Helper functions for index and structure management [Link](i, grandparent)
# --------------------------------------------------- self.bubble_up_max(grandparent)
def parent(self, i): def bubble_up(self, i):
"""Return parent index of node i.""" """Restore heap property after insertion."""
return (i - 1) // 2 if i > 0 else None if i == 0:
def left(self, i): return
"""Return left child index of node i.""" p = [Link](i)
if p is None: ]
return indices = [idx for idx in indices if idx
if [Link](i) % 2 == 0: # even = min level < [Link]]
if [Link][i] > [Link][p]: if not indices:
[Link](i, p) return -1
self.bubble_up_max(p) return max(indices, key=lambda x: [Link][x])
else: def _trickle_down_min(self, i):
self.bubble_up_min(i) """Restore heap property when current level is
else: # odd = max level min."""
if [Link][i] < [Link][p]: m = self._find_smallest_descendant(i)
[Link](i, p) if m == -1:
self.bubble_up_min(p) return
else: if [Link](m) >= [Link](i) + 2: #
self.bubble_up_max(i) grandchild
# --------------------------------------------------- if [Link][m] < [Link][i]:
# Trickle-down operations (restore heap after [Link](m, i)
deletion) p = [Link](m)
# --------------------------------------------------- if [Link][m] > [Link][p]:
def _find_smallest_descendant(self, i): [Link](m, p)
"""Find the index of the smallest descendant self._trickle_down_min(m)
(child/grandchild).""" else: # child
indices = [ if [Link][m] < [Link][i]:
[Link](i), [Link](i), [Link](m, i)
def _trickle_down_max(self, i):
[Link]([Link](i)), [Link]([Link](i)), """Restore heap property when current level is
max."""
[Link]([Link](i)), [Link]([Link](i)) m = self._find_largest_descendant(i)
] if m == -1:
indices = [idx for idx in indices if idx return
< [Link]] if [Link](m) >= [Link](i) + 2: #
if not indices: grandchild
return -1 if [Link][m] > [Link][i]:
return min(indices, key=lambda x: [Link][x]) [Link](m, i)
def _find_largest_descendant(self, i): p = [Link](m)
"""Find the index of the largest descendant if [Link][m] < [Link][p]:
(child/grandchild).""" [Link](m, p)
indices = [ self._trickle_down_max(m)
[Link](i), [Link](i), else: # child
if [Link][m] > [Link][i]:
[Link]([Link](i)), [Link]([Link](i)), [Link](m, i)
def trickle_down(self, i):
[Link]([Link](i)), [Link]([Link](i))
"""Wrapper to call appropriate trickle-down if n == 0:
function.""" return None
if [Link](i) % 2 == 0: elif n == 1:
self._trickle_down_min(i) return [Link]()
else: elif n == 2:
self._trickle_down_max(i) return [Link](1)
# --------------------------------------------------- # Determine which child (1 or 2) has max value
# Core Heap Operations max_index = 1 if [Link][1]
# --------------------------------------------------- > [Link][2] else 2
def insert(self, value): max_val = [Link][max_index]
"""Insert a new value into the heap.""" last = [Link]()
if [Link] >= [Link]: if max_index < len([Link]):
print("Heap is full!") [Link][max_index] = last
return self._trickle_down_max(max_index)
[Link](value) return max_val
self.bubble_up([Link] - 1) def search(self, value):
def get_min(self): """Search for a value in the heap."""
"""Return the minimum element in O(1).""" if value in [Link]:
return [Link][0] if [Link] > 0 else None print(f" {value} found at
def get_max(self): index {[Link](value)}")
"""Return the maximum element in O(1).""" else:
if [Link] == 0: print(f" {value} not found in heap.")
return None def display(self):
elif [Link] == 1: """Display the heap as a list."""
return [Link][0] print("Heap =", [Link])
elif [Link] == 2:
return [Link][1] # ---------------------------------------------------
else: # Interactive Menu for Testing
return max([Link][1], [Link][2]) # ---------------------------------------------------
def delete_min(self): if __name__ == "__main__":
"""Delete and return the minimum element.""" heap = MinMaxHeap()
if [Link] == 0: while True:
return None print("\n--- Min-Max Heap Menu ---")
min_val = [Link][0] print("1. Insert")
last = [Link]() print("2. Get Minimum")
if [Link] > 0: print("3. Get Maximum")
[Link][0] = last print("4. Delete Minimum")
self._trickle_down_min(0) print("5. Delete Maximum")
return min_val print("6. Search")
def delete_max(self): print("7. Display")
"""Delete and return the maximum element.""" print("0. Exit")
n = [Link] choice = input("Enter your choice: ")
if choice == "1":
val = int(input("Enter value to insert: "))
[Link](val)
[Link]()
elif choice == "2":
print("Minimum:", heap.get_min())
elif choice == "3":
print("Maximum:", heap.get_max())
elif choice == "4":
print("Deleted Minimum:", heap.delete_min())
[Link]()
elif choice == "5":
print("Deleted Maximum:", heap.delete_max())
[Link]()
elif choice == "6":
val = int(input("Enter value to search: "))
[Link](val)
elif choice == "7":
[Link]()
elif choice == "0":
print("Exiting...")
break
else:
print("Invalid choice. Please try again.")
if (L == NULL || R == NULL) {
printf("Memory allocation failed!\n");
return;
}

// Copy data to temp 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 temp arrays back into arr[left..right]


int i = 0; // Starting index of left sub-array
int j = 0; // Starting index of right sub-array
int k = left; // Starting index of merged sub-array

Lab – 02 while (i < n1 && j < n2) {


if (L[i] <= R[j]) {
Write a program for implementing the following sorting arr[k] = L[i];
methods: i++;
} else {
a) Merge sort b) Heap sort c) Quick sort arr[k] = R[j];
Merge Sort j++;
}
In C Language : k++;
}
// Merge Sort Algorithm in C
// Documentation: Merge sort divides the array into // Copy remaining elements of L[] if any
halves, sorts them recursively, and merges sorted halves. while (i < n1) {
// Time Complexity: O(n log n) | Space: O(n) arr[k] = L[i];
#include <stdio.h> i++;
#include <stdlib.h> k++;
// Merge function documentation: Merges two sorted halves }
[left...mid] and [mid+1...right]
void merge(int arr[], int left, int mid, int right) { // Copy remaining elements of R[] if any
// Calculate sizes of two sub-arrays while (j < n2) {
int n1 = mid - left + 1; arr[k] = R[j];
int n2 = right - mid; j++;
k++;
// Create temp arrays }
int *L = (int*)malloc(n1 * sizeof(int));
int *R = (int*)malloc(n2 * sizeof(int)); // Free temp arrays
free(L);
free(R); printf("Original array: ");
} printArray(arr, n);
// MergeSort function documentation: Recursively sorts
using divide and conquer mergesort(arr, 0, n - 1);
void mergesort(int arr[], int left, int right) {
if (left < right) { printf("Sorted array: ");
int mid = left + (right - left) / 2; // Avoid printArray(arr, n);
overflow
free(arr); // Free memory
// Sort first half return 0;
mergesort(arr, left, mid); }

// Sort second half


mergesort(arr, mid + 1, right);
C:\Advanced Data Structures Lab\Lab-02>merge_sort.exe
// Merge the sorted halves
Enter the number of elements: 4
merge(arr, left, mid, right);
} Enter 4 elements: 1
} 34
// Print array function 23
void printArray(int arr[], int size) { 12
for (int i = 0; i < size; i++)
Original array: 1 34 23 12
printf("%d ", arr[i]);
printf("\n"); Sorted array: 1 12 23 34
}
// Main - User input
int main() {
int n; In Python :
printf("Enter the number of elements: ");
# Merge Sort Algorithm in Python
scanf("%d", &n);
# Documentation: Merge sort divides the array into halves,
sorts them recursively, and merges sorted halves.
int *arr = (int*)malloc(n * sizeof(int));
# Time Complexity: O(n log n) | Space: O(n)
if (arr == NULL) {
def merge(arr, left, mid, right):
printf("Memory allocation failed!\n");
"""
return 1;
Merges two sorted halves of the array [left...mid] and
}
[mid+1...right].
Documentation: Creates temp arrays, compares and
printf("Enter %d elements: ", n);
merges elements in sorted order.
for (int i = 0; i < n; i++) {
"""
scanf("%d", &arr[i]);
# Calculate sizes
}
n1 = mid - left + 1
n2 = right - mid """
if left < right:
# Create temp arrays mid = left + (right - left) // 2 # Avoid
L = [0] * n1 overflow
R = [0] * n2
# Sort first half
# Copy data to temp arrays mergesort(arr, left, mid)
for i in range(n1):
L[i] = arr[left + i] # Sort second half
for j in range(n2): mergesort(arr, mid + 1, right)
R[j] = arr[mid + 1 + j]
# Merge the sorted halves
# Merge the temp arrays back into arr[left..right] merge(arr, left, mid, right)
i = 0 # Starting index of left sub-array # Main part - User input
j = 0 # Starting index of right sub-array if __name__ == "__main__":
k = left # Starting index of merged sub-array n = int(input("Enter the number of elements: "))
arr = []
while i < n1 and j < n2: print(f"Enter {n} elements: ")
if L[i] <= R[j]: for _ in range(n):
arr[k] = L[i] [Link](int(input()))
i += 1
else: print("Original array:", arr)
arr[k] = R[j]
j += 1 mergesort(arr, 0, len(arr) - 1)
k += 1
print("Sorted array:", arr)
# Copy remaining elements of L[] if any
while i < n1:
arr[k] = L[i] C:\Advanced Data Structures Lab\Lab-02>python merge_sort.py
i += 1 Enter the number of elements: 4
k += 1
Enter 4 elements:
# Copy remaining elements of R[] if any 1
while j < n2: 23
arr[k] = R[j] 12
j += 1 15
k += 1
def mergesort(arr, left, right):
Original array: [1, 23, 12, 15]
""" Sorted array: [1, 12, 15, 23]
Recursively sorts the array using divide and conquer.
Documentation: Base case: if left < right, find mid,
sort left half, sort right half, then merge.
largest = right;

// If largest is not root


if (largest != i) {
// Swap
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;

// Recursively heapify the affected subtree


heapify(arr, n, largest);
}
}
// HeapSort function documentation: First builds max heap,
then extracts elements one by one
void heapsort(int arr[], int n) {
// Build max heap
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
Heap Sort
// One by one extract elements
In C Language : for (int i = n - 1; i > 0; i--) {
// Move current root to end
// Heap Sort Algorithm in C int temp = arr[0];
// Documentation: Builds a max heap from the array, then arr[0] = arr[i];
repeatedly extracts the maximum element and heapifies the arr[i] = temp;
reduced heap.
// Time Complexity: O(n log n) | Space: O(1) - in-place // Call heapify on the reduced heap
#include <stdio.h> heapify(arr, i, 0);
#include <stdlib.h> }
// Heapify function documentation: Ensures the subtree }
rooted at index i satisfies the max heap property // Print array function
void heapify(int arr[], int n, int i) { void printArray(int arr[], int size) {
int largest = i; // Initialize largest as root for (int i = 0; i < size; i++)
int left = 2 * i + 1; printf("%d ", arr[i]);
int right = 2 * i + 2; printf("\n");
}
// See if left child is larger than root // Main - User input
if (left < n && arr[left] > arr[largest]) int main() {
largest = left; int n;
printf("Enter the number of elements: ");
// See if right child is larger than largest so far scanf("%d", &n);
if (right < n && arr[right] > arr[largest])
# Documentation: Builds a max heap from the array, then
int *arr = (int*)malloc(n * sizeof(int)); repeatedly extracts the maximum element and heapifies the
if (arr == NULL) { reduced heap.
printf("Memory allocation failed!\n"); # Time Complexity: O(n log n) | Space: O(1) - in-place
return 1; def heapify(arr, n, i):
} """
Heapify function for max heap.
printf("Enter %d elements: ", n); Documentation: Ensures the subtree rooted at index i
for (int i = 0; i < n; i++) { satisfies the max heap property.
scanf("%d", &arr[i]); Compares parent with its children and swaps with the
} largest if necessary, then recurses.
"""
printf("Original array: "); largest = i # Initialize largest as root
printArray(arr, n); left = 2 * i + 1
right = 2 * i + 2
heapsort(arr, n);
# See if left child is larger than root
printf("Sorted array: "); if left < n and arr[left] > arr[largest]:
printArray(arr, n); largest = left

free(arr); // Free memory # See if right child is larger than largest so far
return 0; if right < n and arr[right] > arr[largest]:
} largest = right

# If largest is not root


if largest != i:
C:\Advanced Data Structures Lab\Lab-02>heap_Sort.exe # Swap
Enter the number of elements: 4 arr[i], arr[largest] = arr[largest], arr[i]
# Recursively heapify the affected subtree
Enter 4 elements: 1 heapify(arr, n, largest)
22 def heapsort(arr):
32 """
12 Main heap sort function.
Original array: 1 22 32 12 Documentation: First builds max heap, then for each
element from end to start: swaps root with end, reduces
Sorted array: 1 12 22 32 heap size, and heapifies root.
"""
n = len(arr)
In Python Language : # Build max heap
# Heap Sort Algorithm in Python for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# One by one extract elements
for i in range(n - 1, 0, -1):
# Move current root to end
arr[0], arr[i] = arr[i], arr[0]
# Call heapify on the reduced heap
heapify(arr, i, 0)
# Main part - User input
if __name__ == "__main__":
n = int(input("Enter the number of elements: "))
arr = []
print(f"Enter {n} elements: ")
for _ in range(n):
[Link](int(input()))

print("Original array:", arr)

heapsort(arr)

print("Sorted array:", arr) Quick Sort


In C Language:
C:\Advanced Data Structures Lab\Lab-02>python heap_sort.py // Quick Sort Algorithm in C
Enter the number of elements: 6 // Documentation: Selects a pivot, partitions the array
Enter 6 elements: around it (smaller elements left, larger right), and
1 recursively sorts sub-arrays.
45 // Time Complexity: Average O(n log n), Worst O(n²) |
Space: O(log n) - recursive calls
23
#include <stdio.h>
12 #include <stdlib.h>
2 // Partition function documentation: Uses last element as
33 pivot. Rearranges array so elements <= pivot left, >
Original array: [1, 45, 23, 12, 2, 33] right
int partition(int arr[], int low, int high) {
Sorted array: [1, 2, 12, 23, 33, 45]
int pivot = arr[high]; // Choose last element as
pivot
int i = low - 1; // Index of smaller element

for (int j = low; j < high; j++) {


if (arr[j] <= pivot) {
i++;
// Swap arr[i] and arr[j]
int temp = arr[i]; }
arr[i] = arr[j];
arr[j] = temp; printf("Enter %d elements: ", n);
} for (int i = 0; i < n; i++) {
} scanf("%d", &arr[i]);
}
// Swap pivot with i+1
int temp = arr[i + 1]; printf("Original array: ");
arr[i + 1] = arr[high]; printArray(arr, n);
arr[high] = temp;
quicksort(arr, 0, n - 1);
return i + 1; // Return partition index
} printf("Sorted array: ");
// QuickSort function documentation: Recursively sorts by printArray(arr, n);
partitioning
void quicksort(int arr[], int low, int high) { free(arr); // Free memory
if (low < high) { return 0;
// Partition the array }
int pi = partition(arr, low, high);

// Recursively sort elements before and after C:\Advanced Data Structures Lab\Lab-02>quick_sort.exe
partition
Enter the number of elements: 4
quicksort(arr, low, pi - 1); // Left sub-array
quicksort(arr, pi + 1, high); // Right sub-array Enter 4 elements: 12
} 1
} 2
// Print array function 27
void printArray(int arr[], int size) {
Original array: 12 1 2 27
for (int i = 0; i < size; i++)
printf("%d ", arr[i]); Sorted array: 1 2 12 27
printf("\n");
}
// Main - User input
int main() {
int n;
printf("Enter the number of elements: "); In Python Language:
scanf("%d", &n); # Quick Sort Algorithm in Python
# Documentation: Selects a pivot, partitions the array
int *arr = (int*)malloc(n * sizeof(int)); around it (smaller elements left, larger right), and
if (arr == NULL) { recursively sorts sub-arrays.
printf("Memory allocation failed!\n"); # Time Complexity: Average O(n log n), Worst O(n²) |
return 1; Space: O(log n) - recursive calls
def partition(arr, low, high): print("Original array:", arr)
"""
Partition function for quick sort. quicksort(arr, 0, len(arr) - 1)
Documentation: Uses last element as pivot. Rearranges
array so elements <= pivot are left, > pivot are right. print("Sorted array:", arr)
Returns the partition index (pivot's final position).
"""
pivot = arr[high] # Choose last element as pivot
i = low - 1 # Index of smaller element C:\Advanced Data Structures Lab\Lab-02>python quick_sort.py
Enter the number of elements: 3
for j in range(low, high):
if arr[j] <= pivot:
Enter 3 elements:
i += 1 23
# Swap arr[i] and arr[j] 1
arr[i], arr[j] = arr[j], arr[i] 22
Original array: [23, 1, 22]
# Swap pivot with i+1
arr[i + 1], arr[high] = arr[high], arr[i + 1]
Sorted array: [1, 22, 23]
return i + 1 # Return partition index
def quicksort(arr, low, high):
"""
Main quick sort function.
Documentation: Recursively sorts by partitioning: if Lab – 01
low < high, partition, then sort left and right sub-
arrays. Write a program to perform the following operations:
""" a) Insert an element into a binary search tree.
if low < high:
b) Delete an element from a binary search tree.
# Partition the array
pi = partition(arr, low, high) c) Search for a key element in a binary search
tree.
# Recursively sort elements before partition and
after
In C Language:
quicksort(arr, low, pi - 1) # Left sub-array
quicksort(arr, pi + 1, high) # Right sub-array
# Main part - User input #include <stdio.h>
if __name__ == "__main__": #include <stdlib.h>
n = int(input("Enter the number of elements: "))
arr = [] // BST Node structure
print(f"Enter {n} elements: ") struct Node {
for _ in range(n):
int data;
[Link](int(input()))
struct Node* left;
struct Node* right;
}; // Find minimum value (leftmost node)
int minValue(struct Node* root) {
// Initialize empty BST (root = NULL) struct Node* current = root;
struct Node* initialize() { while (current && current->left != NULL) {
return NULL; current = current->left;
} }
if (current) return current->data;
// Create/Insert a new node (recursive) return -1; // Empty tree
struct Node* insert(struct Node* root, int data) { }
if (root == NULL) {
struct Node* newNode = (struct // Find maximum value (rightmost node)
Node*)malloc(sizeof(struct Node)); int maxValue(struct Node* root) {
newNode->data = data; struct Node* current = root;
newNode->left = NULL; while (current && current->right != NULL) {
newNode->right = NULL; current = current->right;
return newNode; }
} if (current) return current->data;
if (data < root->data) { return -1; // Empty tree
root->left = insert(root->left, data); }
} else if (data > root->data) {
root->right = insert(root->right, data); // Delete a node (three cases: leaf, one child, two
} children)
return root; struct Node* deleteNode(struct Node* root, int data) {
} if (root == NULL) return root;

// Search for a key if (data < root->data) {


struct Node* search(struct Node* root, int data) { root->left = deleteNode(root->left, data);
if (root == NULL || root->data == data) { } else if (data > root->data) {
return root; root->right = deleteNode(root->right, data);
} } else {
if (data < root->data) { // Node found
return search(root->left, data); if (root->left == NULL) { // Leaf or right child
} only
return search(root->right, data); struct Node* temp = root->right;
} free(root);
return temp; }
} else if (root->right == NULL) { // Left child
only // Main function with UI (switch-case menu)
struct Node* temp = root->left; int main() {
free(root); struct Node* root = initialize(); // Start with empty
return temp; tree
} int choice, data;
// Two children: Get inorder successor (min in
right subtree) printf("=== Binary Search Tree Operations ===\n");
struct Node* temp = root->right; printf("1. Insert Node (Single)\n");
while (temp->left != NULL) { printf("2. Delete Node\n");
temp = temp->left; printf("3. Search Node\n");
} printf("4. Find Min Value\n");
root->data = temp->data; // Copy successor data printf("5. Find Max Value\n");
root->right = deleteNode(root->right, temp->data); printf("6. Inorder Traversal\n");
// Delete successor printf("7. Build Tree from Multiple Inputs (Existing
} Tree Load - Enter -1 to stop)\n");
return root; printf("0. Exit\n");
}
while (1) {
// Inorder traversal (Left-Root-Right, sorted order) printf("\nEnter your choice: ");
void inorder(struct Node* root) { scanf("%d", &choice);
if (root != NULL) {
inorder(root->left); switch (choice) {
printf("%d ", root->data); case 1:
inorder(root->right); printf("Enter data to insert: ");
} scanf("%d", &data);
} root = insert(root, data);
printf("%d inserted successfully!\n",
// Free tree memory (postorder) data);
void freeTree(struct Node* root) { break;
if (root != NULL) {
freeTree(root->left); case 2:
freeTree(root->right); printf("Enter data to delete: ");
free(root); scanf("%d", &data);
} if (search(root, data)) {
root = deleteNode(root, data);
printf("%d deleted successfully!\n", case 6:
data); if (root) {
} else { printf("Inorder Traversal (Sorted):
printf("%d not found!\n", data); ");
} inorder(root);
break; printf("\n");
} else {
case 3: printf("Tree is empty!\n");
printf("Enter data to search: "); }
scanf("%d", &data); break;
if (search(root, data)) {
printf("%d found in the tree!\n", case 7:
data); printf("Enter values to build tree (space
} else { separated, -1 to stop): ");
printf("%d not found!\n", data); while (scanf("%d", &data) == 1 && data !=
} -1) {
break; root = insert(root, data);
printf("%d inserted. Continue...\n",
case 4: data);
if (root) { }
printf("Minimum value: %d\n", printf("Tree building complete!\n");
minValue(root)); break;
} else {
printf("Tree is empty!\n"); case 0:
} printf("Exiting... Freeing memory.\n");
break; freeTree(root);
return 0;
case 5:
if (root) { default:
printf("Maximum value: %d\n", printf("Invalid choice! Try again.\n");
maxValue(root)); }
} else { }
printf("Tree is empty!\n"); return 0;
} }
break;
In Python Language:
# Find maximum value (rightmost node)
class Node: def max_value(root):
def __init__(self, data): current = root
[Link] = data while current and [Link]:
[Link] = None current = [Link]
[Link] = None return [Link] if current else -1 # Empty tree

# Initialize empty BST (root = None) # Delete a node (three cases: leaf, one child, two
def initialize(): children)
return None def delete_node(root, data):
if root is None:
# Create/Insert a new node (recursive) return root
def insert(root, data):
if root is None: if data < [Link]:
return Node(data) [Link] = delete_node([Link], data)
if data < [Link]: elif data > [Link]:
[Link] = insert([Link], data) [Link] = delete_node([Link], data)
elif data > [Link]: else:
[Link] = insert([Link], data) # Node found
return root if [Link] is None: # Leaf or right child only
return [Link]
# Search for a key elif [Link] is None: # Left child only
def search(root, data): return [Link]
if root is None or [Link] == data:
return root # Two children: Get inorder successor (min in
if data < [Link]: right subtree)
return search([Link], data) temp = [Link]
return search([Link], data) while [Link]:
temp = [Link]
# Find minimum value (leftmost node) [Link] = [Link] # Copy successor data
def min_value(root): [Link] = delete_node([Link], [Link]) #
current = root Delete successor
while current and [Link]:
current = [Link] return root
return [Link] if current else -1 # Empty tree
# Inorder traversal (Left-Root-Right, sorted order) print(f"{data} inserted successfully!")
def inorder(root):
if root: elif choice == 2:
inorder([Link]) data = int(input("Enter data to delete: "))
print([Link], end=' ') if search(root, data):
inorder([Link]) root = delete_node(root, data)
print(f"{data} deleted successfully!")
# Optional: Delete tree (Python GC handles, but for else:
completeness) print(f"{data} not found!")
def delete_tree(root):
if root: elif choice == 3:
delete_tree([Link]) data = int(input("Enter data to search: "))
delete_tree([Link]) if search(root, data):
del root # Or root = None print(f"{data} found in the tree!")
else:
# Main function with UI (if-elif menu loop) print(f"{data} not found!")
def main():
root = initialize() # Start with empty tree elif choice == 4:
if root:
print("=== Binary Search Tree Operations ===") print(f"Minimum value:
print("1. Insert Node") {min_value(root)}")
print("2. Delete Node") else:
print("3. Search Node") print("Tree is empty!")
print("4. Find Min Value")
print("5. Find Max Value") elif choice == 5:
print("6. Inorder Traversal") if root:
print("7. Build Tree from Multiple Inputs (Enter -1 to print(f"Maximum value:
stop)") {max_value(root)}")
print("0. Exit") else:
print("Tree is empty!")
while True:
choice = int(input("\nEnter your choice: ")) elif choice == 6:
if root:
if choice == 1: print("Inorder Traversal (Sorted): ",
data = int(input("Enter data to insert: ")) end='')
root = insert(root, data) inorder(root)
print()
else:
print("Tree is empty!")

elif choice == 7:
print("Enter values to build tree (-1 to
stop): ")
while True:
try:
data = int(input())
if data == -1:
break
root = insert(root, data)
print(f"{data} inserted.
Continue...")
except ValueError:
print("Invalid input! Enter
integer.")
print("Tree building complete!")

elif choice == 0:
print("Exiting... Deleting tree.")
delete_tree(root)
break

else:
print("Invalid choice! Try again.")

if __name__ == "__main__":
main()

You might also like