Monday, May 29, 2023

Quick Sort: Algorithm & Implementation

 

Quick Sort: Algorithm & Implementation

1️⃣ What is Quick Sort?

🔹 Quick Sort is a divide-and-conquer sorting algorithm.
🔹 It selects a pivot element and partitions the array so that:

  • Elements smaller than pivot go to the left.
  • Elements greater than pivot go to the right.
    🔹 The process repeats recursively until the array is sorted.

✅ Time Complexity

CaseComplexity
Best Case (Balanced Partitioning)O(n log n)
Average CaseO(n log n)
Worst Case (Already Sorted, Unbalanced Partitioning)O(n²)

✅ Space Complexity

  • O(log n) (for recursive stack calls)

✅ Is it Stable?

❌ No (Relative order of equal elements may change)


2️⃣ How Quick Sort Works

🔹 Select a pivot element.
🔹 Partition the array so that:

  • Left part contains elements < pivot
  • Right part contains elements > pivot
    🔹 Recursively sort left and right partitions.

Step-by-Step Example

📝 Input: [10, 80, 30, 90, 40, 50, 70]
Pivot = 70 (can be any element, commonly last, first, or random)

StepArray StatePartitioning Around Pivot
1[10, 30, 40, 50, 70, 90, 80]Pivot 70 placed correctly
2`[10, 30, 40, 50]70
3`[10, 30]40

🔹 Final Sorted Array: [10, 30, 40, 50, 70, 80, 90]


3️⃣ Quick Sort Algorithm

🔹 Pseudocode


QuickSort(arr, low, high): if low < high: pivotIndex = Partition(arr, low, high) QuickSort(arr, low, pivotIndex - 1) QuickSort(arr, pivotIndex + 1, high) Partition(arr, low, high): pivot = arr[high] i = low - 1 for j = low to high - 1: if arr[j] < pivot: i++ Swap arr[i] and arr[j] Swap arr[i+1] and arr[high] return i+1

4️⃣ Quick Sort Implementation in C


#include <stdio.h> // Function to swap two elements void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } // Partition function to place pivot in correct position int partition(int arr[], int low, int high) { int pivot = arr[high]; // Choosing last element as pivot int i = low - 1; for (int j = low; j < high; j++) { if (arr[j] < pivot) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return (i + 1); } // QuickSort function void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } // Function to print an array void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } // Main function int main() { int arr[] = {10, 80, 30, 90, 40, 50, 70}; int n = sizeof(arr) / sizeof(arr[0]); printf("Original array: "); printArray(arr, n); quickSort(arr, 0, n - 1); printf("Sorted array: "); printArray(arr, n); return 0; }

🔹 Output


Original array: 10 80 30 90 40 50 70 Sorted array: 10 30 40 50 70 80 90

5️⃣ Advantages & Disadvantages

✅ Advantages

✔ Faster than other O(n²) algorithms like Selection and Insertion Sort.
✔ Efficient for large datasets (O(n log n) in average case).
✔ In-place sorting (O(log n) extra space for recursion).

❌ Disadvantages

❌ Worst case O(n²) if pivot selection is poor (already sorted or reversed).
❌ Not stable (relative order of equal elements may change).
❌ Uses recursion, which may cause stack overflow for large arrays.


6️⃣ When to Use Quick Sort?

🔹 Best for large datasets (better than Bubble, Insertion, or Selection Sort).
🔹 Useful when in-place sorting is required (O(1) extra space).
🔹 Not ideal if stable sorting is required (use Merge Sort instead).

💡 For best performance, use a randomized or median pivot selection! 🚀

Wednesday, May 17, 2023

Selection Sort: Algorithm & Implementation

 

Selection Sort: Algorithm & Implementation

1️⃣ What is Selection Sort?

🔹 Selection Sort is a simple comparison-based sorting algorithm.
🔹 It selects the smallest (or largest) element from the unsorted part and swaps it with the first element of the unsorted part.
🔹 It continues this process until the entire array is sorted.

✅ Time Complexity

CaseComplexity
Best Case (Already Sorted)O(n²)
Average CaseO(n²)
Worst Case (Reversed Order)O(n²)

✅ Space Complexity

  • O(1) (In-place sorting)

✅ Is it Stable?

❌ No (It may change the relative order of equal elements)


2️⃣ How Selection Sort Works

🔹 The algorithm divides the array into sorted and unsorted parts.
🔹 It finds the minimum element in the unsorted part and swaps it with the first element of the unsorted part.
🔹 This process is repeated for all elements.

Step-by-Step Example

📝 Input: [29, 10, 14, 37, 13]

StepArray StateMinimum FoundSwap Performed
1[29, 10, 14, 37, 13]10Swap 29 ↔ 10
2[10, 29, 14, 37, 13]13Swap 29 ↔ 13
3[10, 13, 14, 37, 29]14No swap needed
4[10, 13, 14, 37, 29]29Swap 37 ↔ 29
5[10, 13, 14, 29, 37]37No swap needed

🔹 Final Sorted Array: [10, 13, 14, 29, 37]


3️⃣ Selection Sort Algorithm

🔹 Pseudocode


for i = 0 to n-2: minIndex = i for j = i+1 to n-1: if arr[j] < arr[minIndex]: minIndex = j Swap arr[i] and arr[minIndex]

4️⃣ Selection Sort Implementation in C


#include <stdio.h> // Function to perform Selection Sort void selectionSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { int minIndex = i; // Find the minimum element in the remaining unsorted array for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } // Swap the found minimum element with the first element int temp = arr[minIndex]; arr[minIndex] = arr[i]; arr[i] = temp; } } // Function to print an array void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } // Main function int main() { int arr[] = {29, 10, 14, 37, 13}; int n = sizeof(arr) / sizeof(arr[0]); printf("Original array: "); printArray(arr, n); selectionSort(arr, n); printf("Sorted array: "); printArray(arr, n); return 0; }

🔹 Output


Original array: 29 10 14 37 13 Sorted array: 10 13 14 29 37

5️⃣ Advantages & Disadvantages

✅ Advantages

✔ Simple & easy to implement
✔ Works well for small datasets
✔ Performs well when memory writes are costly (e.g., flash memory)
✔ Does not require extra memory (O(1) space complexity)

❌ Disadvantages

❌ Inefficient for large datasets (O(n²))
❌ Slower than Quick Sort & Merge Sort
❌ Not a stable sorting algorithm


6️⃣ When to Use Selection Sort?

🔹 Best for small datasets (e.g., <100 elements).
🔹 Good when memory writes are expensive (fewer swaps).
🔹 Not ideal for large datasets; use Merge Sort or Quick Sort instead. 🚀

Sunday, May 14, 2023

Selection Sort: Algorithm & Implementation

 

Selection Sort: Algorithm & Implementation

1️⃣ What is Selection Sort?

🔹 Selection Sort is a simple comparison-based sorting algorithm.
🔹 It selects the smallest (or largest) element from the unsorted part and swaps it with the first element of the unsorted part.
🔹 It continues this process until the entire array is sorted.

✅ Time Complexity

CaseComplexity
Best Case (Already Sorted)O(n²)
Average CaseO(n²)
Worst Case (Reversed Order)O(n²)

✅ Space Complexity

  • O(1) (In-place sorting)

✅ Is it Stable?

❌ No (It may change the relative order of equal elements)


2️⃣ How Selection Sort Works

🔹 The algorithm divides the array into sorted and unsorted parts.
🔹 It finds the minimum element in the unsorted part and swaps it with the first element of the unsorted part.
🔹 This process is repeated for all elements.

Step-by-Step Example

📝 Input: [29, 10, 14, 37, 13]

StepArray StateMinimum FoundSwap Performed
1[29, 10, 14, 37, 13]10Swap 29 ↔ 10
2[10, 29, 14, 37, 13]13Swap 29 ↔ 13
3[10, 13, 14, 37, 29]14No swap needed
4[10, 13, 14, 37, 29]29Swap 37 ↔ 29
5[10, 13, 14, 29, 37]37No swap needed

🔹 Final Sorted Array: [10, 13, 14, 29, 37]


3️⃣ Selection Sort Algorithm

🔹 Pseudocode


for i = 0 to n-2: minIndex = i for j = i+1 to n-1: if arr[j] < arr[minIndex]: minIndex = j Swap arr[i] and arr[minIndex]

4️⃣ Selection Sort Implementation in C


#include <stdio.h> // Function to perform Selection Sort void selectionSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { int minIndex = i; // Find the minimum element in the remaining unsorted array for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } // Swap the found minimum element with the first element int temp = arr[minIndex]; arr[minIndex] = arr[i]; arr[i] = temp; } } // Function to print an array void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } // Main function int main() { int arr[] = {29, 10, 14, 37, 13}; int n = sizeof(arr) / sizeof(arr[0]); printf("Original array: "); printArray(arr, n); selectionSort(arr, n); printf("Sorted array: "); printArray(arr, n); return 0; }

🔹 Output


Original array: 29 10 14 37 13 Sorted array: 10 13 14 29 37

5️⃣ Advantages & Disadvantages

✅ Advantages

✔ Simple & easy to implement
✔ Works well for small datasets
✔ Performs well when memory writes are costly (e.g., flash memory)
✔ Does not require extra memory (O(1) space complexity)

❌ Disadvantages

❌ Inefficient for large datasets (O(n²))
❌ Slower than Quick Sort & Merge Sort
❌ Not a stable sorting algorithm


6️⃣ When to Use Selection Sort?

🔹 Best for small datasets (e.g., <100 elements).
🔹 Good when memory writes are expensive (fewer swaps).
🔹 Not ideal for large datasets; use Merge Sort or Quick Sort instead. 

Thursday, May 11, 2023

Insertion Sort: Algorithm & Implementation

 

Insertion Sort: Algorithm & Implementation

1️⃣ What is Insertion Sort?

🔹 Insertion Sort is a simple sorting algorithm that builds the sorted array one item at a time.
🔹 It compares each element with the previous ones and inserts it at the correct position.
🔹 Best suited for small or nearly sorted datasets.

✅ Time Complexity

CaseComplexity
Best Case (Already Sorted)O(n)
Average CaseO(n²)
Worst Case (Reversed Order)O(n²)

✅ Space Complexity

  • O(1) (In-place sorting)

✅ Is it Stable?

✔ Yes (Preserves order of equal elements)


2️⃣ How Insertion Sort Works

🔹 The algorithm divides the array into sorted and unsorted parts.
🔹 It picks an element from the unsorted part and inserts it into the correct position in the sorted part.

Step-by-Step Example

📝 Input: [8, 4, 1, 6, 3]

StepKey ElementSorted PartUnsorted PartAction
1484, 1, 6, 3Move 8 right, Insert 4
214, 81, 6, 3Move 8, 4 right, Insert 1
361, 4, 86, 3Move 8 right, Insert 6
431, 4, 6, 83Move 6, 4 right, Insert 3

🔹 Final Sorted Array: [1, 3, 4, 6, 8]


3️⃣ Insertion Sort Algorithm

🔹 Pseudocode


for i = 1 to n-1: key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j + 1] = arr[j] // Shift element right j = j - 1 arr[j + 1] = key // Insert key at the correct position

4️⃣ Insertion Sort Implementation in C


#include <stdio.h> // Function to perform Insertion Sort void insertionSort(int arr[], int n) { for (int i = 1; i < n; i++) { int key = arr[i]; int j = i - 1; // Move elements that are greater than key one position ahead while (j >= 0 && arr[j] > key) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = key; } } // Function to print an array void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } // Main function int main() { int arr[] = {12, 11, 13, 5, 6}; int n = sizeof(arr) / sizeof(arr[0]); printf("Original array: "); printArray(arr, n); insertionSort(arr, n); printf("Sorted array: "); printArray(arr, n); return 0; }

🔹 Output


Original array: 12 11 13 5 6 Sorted array: 5 6 11 12 13

5️⃣ Advantages & Disadvantages

✅ Advantages

✔ Simple & easy to implement
✔ Works well for small datasets
✔ Efficient for nearly sorted data (O(n) best case)
✔ In-place sorting (O(1) space)

❌ Disadvantages

❌ Inefficient for large datasets (O(n²) worst case)
❌ Slower than Quick Sort & Merge Sort for large inputs


6️⃣ When to Use Insertion Sort?

🔹 Best for small datasets (e.g., <100 elements).
🔹 Great for nearly sorted data (performs in O(n) time).
🔹 Used in real-world scenarios like card sorting or keyboard typing auto-sorting.

💡 For larger datasets, use Merge Sort or Quick Sort! 🚀

Thursday, May 4, 2023

Sorting in Data Structures

 

Sorting in Data Structures

1️⃣ What is Sorting?

Sorting is the process of arranging elements in a particular order (ascending or descending). It helps in efficient searching, data retrieval, and processing.

2️⃣ Types of Sorting Algorithms

Sorting algorithms are mainly categorized into:

  • Comparison-based Sorting (Bubble Sort, Selection Sort, Quick Sort, Merge Sort, etc.)
  • Non-comparison Sorting (Counting Sort, Radix Sort, Bucket Sort, etc.)

3️⃣ Common Sorting Algorithms

AlgorithmBest CaseWorst CaseAverage CaseSpace ComplexityStable?
Bubble SortO(n)O(n²)O(n²)O(1)✅ Yes
Selection SortO(n²)O(n²)O(n²)O(1)❌ No
Insertion SortO(n)O(n²)O(n²)O(1)✅ Yes
Merge SortO(n log n)O(n log n)O(n log n)O(n)✅ Yes
Quick SortO(n log n)O(n²)O(n log n)O(log n)❌ No
Heap SortO(n log n)O(n log n)O(n log n)O(1)❌ No
Counting SortO(n + k)O(n + k)O(n + k)O(n + k)✅ Yes
Radix SortO(nk)O(nk)O(nk)O(n + k)✅ Yes

4️⃣ Sorting Algorithm Implementations in C

✅ 1. Bubble Sort (Simple but Inefficient)

Bubble Sort repeatedly swaps adjacent elements if they are in the wrong order.


#include <stdio.h> void bubbleSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { // Swap int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } int main() { int arr[] = {5, 3, 8, 4, 2}; int n = sizeof(arr) / sizeof(arr[0]); bubbleSort(arr, n); printf("Sorted array: "); printArray(arr, n); return 0; }

✅ Simple but slow (O(n²))
❌ Not suitable for large datasets


✅ 2. Insertion Sort (Efficient for Small Datasets)

Insertion Sort builds a sorted array one item at a time.


#include <stdio.h> void insertionSort(int arr[], int n) { for (int i = 1; i < n; i++) { int key = arr[i]; int j = i - 1; while (j >= 0 && arr[j] > key) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = key; } } void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } int main() { int arr[] = {9, 7, 5, 3, 1}; int n = sizeof(arr) / sizeof(arr[0]); insertionSort(arr, n); printf("Sorted array: "); printArray(arr, n); return 0; }

✅ Good for small datasets (O(n²))
✅ Performs well when data is nearly sorted


✅ 3. Merge Sort (Efficient, Uses Divide & Conquer)

Merge Sort divides the array into two halves, sorts them, and merges them.


#include <stdio.h> void merge(int arr[], int left, int mid, int right) { int n1 = mid - left + 1; int n2 = right - mid; int L[n1], R[n2]; 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]; int i = 0, j = 0, k = left; while (i < n1 && j < n2) { if (L[i] <= R[j]) arr[k++] = L[i++]; else arr[k++] = R[j++]; } while (i < n1) arr[k++] = L[i++]; while (j < n2) arr[k++] = R[j++]; } void mergeSort(int arr[], int left, int right) { if (left < right) { int mid = left + (right - left) / 2; mergeSort(arr, left, mid); mergeSort(arr, mid + 1, right); merge(arr, left, mid, right); } } void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } int main() { int arr[] = {12, 11, 13, 5, 6, 7}; int n = sizeof(arr) / sizeof(arr[0]); mergeSort(arr, 0, n - 1); printf("Sorted array: "); printArray(arr, n); return 0; }

✅ Efficient (O(n log n))
❌ Uses extra memory (O(n))


✅ 4. Quick Sort (Best for Large Datasets)

Quick Sort picks a pivot, partitions the array, and recursively sorts both halves.


#include <stdio.h> void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } int partition(int arr[], int low, int high) { int pivot = arr[high]; int i = (low - 1); for (int j = low; j < high; j++) { if (arr[j] < pivot) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return (i + 1); } void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } void printArray(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } int main() { int arr[] = {10, 7, 8, 9, 1, 5}; int n = sizeof(arr) / sizeof(arr[0]); quickSort(arr, 0, n - 1); printf("Sorted array: "); printArray(arr, n); return 0; }

✅ Fastest in practice (O(n log n) average case)
❌ Worst-case O(n²) if poorly implemented

Complete Binary Tree in Data Structures

  Complete Binary Tree in Data Structures 🌳 A Complete Binary Tree (CBT) is a type of Binary Tree where: ✔ All levels except possibly t...