Sorting — From Bubble to Radix

৭+টি sort, runnable demo-সহ

~55 min Advanced 25 practice problems Live code

1. Why Sort?

Sorted data binary search, dedup, median, range query — সব কিছু সহজ করে। Algorithm-এর সবচেয়ে বেশি studied family।

2. The Big Comparison Table

AlgorithmBestAvgWorstSpaceStable
BubbleO(n)O(n²)O(n²)O(1)yes
SelectionO(n²)O(n²)O(n²)O(1)no
InsertionO(n)O(n²)O(n²)O(1)yes
MergeO(n log n)O(n log n)O(n log n)O(n)yes
QuickO(n log n)O(n log n)O(n²)O(log n)no
HeapO(n log n)O(n log n)O(n log n)O(1)no
CountingO(n+k)O(n+k)O(n+k)O(k)yes
RadixO(d(n+k))——O(n+k)yes

3. Insertion Sort (nearly-sorted-এ সেরা)

insertion.c
#include <stdio.h>

void insertion_sort(int *a, int n) {
    for (int i = 1; i < n; i++) {
        int key = a[i], j = i - 1;
        while (j >= 0 && a[j] > key) { a[j+1] = a[j]; j--; }
        a[j+1] = key;
    }
}

int main(void) {
    int a[] = {42, 7, 13, 2, 99, 8, 25};
    int n = 7;
    insertion_sort(a, n);
    for (int i = 0; i < n; i++) printf("%d ", a[i]);
    putchar('\n');
    return 0;
}

4. Merge Sort (guaranteed O(n log n), stable)

merge_sort.c
#include <stdio.h>
#include <stdlib.h>

void merge(int *a, int l, int m, int r) {
    int n = r - l + 1, *buf = malloc(n * sizeof *buf);
    int i = l, j = m + 1, k = 0;
    while (i <= m && j <= r) buf[k++] = (a[i] <= a[j]) ? a[i++] : a[j++];
    while (i <= m) buf[k++] = a[i++];
    while (j <= r) buf[k++] = a[j++];
    for (int x = 0; x < n; x++) a[l + x] = buf[x];
    free(buf);
}

void merge_sort(int *a, int l, int r) {
    if (l >= r) return;
    int m = l + (r - l) / 2;
    merge_sort(a, l, m);
    merge_sort(a, m + 1, r);
    merge(a, l, m, r);
}

int main(void) {
    int a[] = {5, 2, 8, 1, 9, 3, 7, 4, 6};
    int n = 9;
    merge_sort(a, 0, n - 1);
    for (int i = 0; i < n; i++) printf("%d ", a[i]);
    putchar('\n');
    return 0;
}

5. Quick Sort (practice-এ সবচেয়ে দ্রুত)

quick.c
#include <stdio.h>

static int partition(int *a, int l, int r) {
    int pivot = a[r], i = l - 1;
    for (int j = l; j < r; j++) {
        if (a[j] <= pivot) {
            i++;
            int t = a[i]; a[i] = a[j]; a[j] = t;
        }
    }
    int t = a[i + 1]; a[i + 1] = a[r]; a[r] = t;
    return i + 1;
}

void quick_sort(int *a, int l, int r) {
    if (l < r) {
        int p = partition(a, l, r);
        quick_sort(a, l, p - 1);
        quick_sort(a, p + 1, r);
    }
}

int main(void) {
    int a[] = {10, 7, 8, 9, 1, 5};
    int n = 6;
    quick_sort(a, 0, n - 1);
    for (int i = 0; i < n; i++) printf("%d ", a[i]);
    putchar('\n');
    return 0;
}

Worst O(n²) এড়াতে random pivot নিন: int p = l + rand() % (r - l + 1); তারপর a[p] ও a[r] swap।

6. Stability Matters

Stable sort সমান key-এর relative order বজায় রাখে — একাধিক field-এ sort করার সময় গুরুত্বপূর্ণ (আগে city sort, তারপর name sort → একই name-এ city order বজায় থাকবে)।

7. Practice Problems

  1. Implement bubble, selection, insertion.
    তিনটি O(n²) sort।
    ✨ Show Answer
    three.c
    #include <stdio.h>
    void bubble(int *a, int n) {
        for (int i = 0; i < n-1; i++)
            for (int j = 0; j < n-1-i; j++)
                if (a[j] > a[j+1]) { int t = a[j]; a[j] = a[j+1]; a[j+1] = t; }
    }
    void selection(int *a, int n) {
        for (int i = 0; i < n-1; i++) {
            int m = i;
            for (int j = i+1; j < n; j++) if (a[j] < a[m]) m = j;
            int t = a[i]; a[i] = a[m]; a[m] = t;
        }
    }
    int main(void) {
        int a[] = {5, 2, 8, 1, 9};
        bubble(a, 5);
        for (int i = 0; i < 5; i++) printf("%d ", a[i]);
        putchar('\n');
        return 0;
    }
  2. Implement merge sort.
    Merge sort।
    ✨ Show Answer

    Section 4 দেখুন।

  3. Implement quicksort with random pivot.
    Random pivot-এর quicksort।
    ✨ Show Answer

    Section 5-এর code-এ partition-এর শুরুতে int p = l + rand()%(r-l+1); swap(a[p], a[r]) যোগ করুন।

  4. Implement heapsort.
    Heapsort।
    ✨ Show Answer

    Array-এ max-heap build (bottom-up sift-down), তারপর বারবার root swap-with-last, heap size কমান, sift-down। O(n log n), in-place।

  5. Counting sort for ints in [0, k].
    Counting sort।
    ✨ Show Answer
    void counting_sort(int *a, int n, int k) {
        int *c = calloc(k + 1, sizeof *c);
        for (int i = 0; i < n; i++) c[a[i]]++;
        int p = 0;
        for (int v = 0; v <= k; v++)
            while (c[v]--) a[p++] = v;
        free(c);
    }
  6. Radix sort for 32-bit unsigned integers.
    Radix sort।
    ✨ Show Answer

    প্রতিটি digit (বা byte)-এর জন্য stable counting sort, LSB থেকে MSB-তে। k = 256, d = 4 passes — মোট O(4(n + 256))।

  7. Compare all 6 sorts on n = 10⁵.
    ৬টি sort তুলনা।
    ✨ Show Answer

    n = 10⁵-এ O(n²) sorts ~10¹⁰ ops, কয়েক সেকেন্ড; O(n log n) ~10⁷, মিলিসেকেন্ড। clock() দিয়ে benchmark করুন।

  8. Sort structs by two fields (primary, secondary).
    দুটি field-এ sort।
    ✨ Show Answer

    Compare function-এ প্রথমে primary field মিলান, সমান হলে secondary। Stable sort থাকলে আগে secondary, পরে primary আলাদা pass-এও কাজ করে।

  9. Quickselect: kth smallest in O(n) avg.
    Kth smallest — O(n) avg।
    ✨ Show Answer

    Quicksort-এর partition ব্যবহার করুন; শুধু k-side-এ recurse। T(n) = T(n/2) + n → O(n) amortized।

  10. Median of medians — worst-case O(n).
    Median of medians — worst-case O(n)।
    ✨ Show Answer

    Array-কে 5-element group-এ ভাগ করুন; প্রতিটি group-এর median; সেই median-গুলোর median বের করে pivot হিসেবে ব্যবহার। Worst-case Θ(n), কিন্তু constant বড় — practice-এ quickselect-ই দ্রুত।

  11. Sort a nearly-sorted array (k-away) — which algo?
    Nearly-sorted-এ কোন algo?
    ✨ Show Answer

    Insertion sort O(nk) — k ছোট হলে O(n)। Tim sort এই idea-ই ব্যবহার করে (small run-এ insertion + merge)।

  12. Sort a linked list via merge sort.
    Linked list-এ merge sort।
    ✨ Show Answer

    Slow/fast দিয়ে middle বের করুন, split, recursively sort, merge। Extra array লাগে না।

  13. Custom comparator via function pointer (qsort).
    qsort-এ custom compare।
    ✨ Show Answer

    L22-এর qsort_int.c reference। Compare-এ (x > y) - (x < y) overflow এড়ায়।

  14. Sort strings lexicographically.
    String lexicographic sort।
    ✨ Show Answer
    int cmp_str(const void *a, const void *b) {
        return strcmp(*(const char *const*)a, *(const char *const*)b);
    }
    qsort(arr, n, sizeof arr[0], cmp_str);
  15. Dutch National Flag (3-way partition).
    Dutch flag algorithm।
    ✨ Show Answer

    Three pointers: low, mid, high। a[mid] = 0 → swap(low, mid), low++, mid++। = 1 → mid++। = 2 → swap(mid, high), high--। O(n)।

  16. Sort colors (0/1/2).
    0/1/2 color sort।
    ✨ Show Answer

    উপরের Dutch-flag-ই উত্তর। Counting sort-ও চলবে কিন্তু এক-pass O(n), O(1) space-এ Dutch flag সেরা।

  17. External merge sort for a file too big for RAM.
    RAM-এর চেয়ে বড় file-এ external merge sort।
    ✨ Show Answer

    File-কে RAM-size chunk-এ ভাগ করুন; প্রতিটি in-memory sort করে temp file-এ লিখুন। তারপর k-way merge (min-heap) দিয়ে মেলান।

  18. Why is quicksort faster than merge sort in practice?
    Quicksort practice-এ দ্রুত কেন?
    ✨ Show Answer

    In-place (extra allocation নেই), cache-friendly (sequential scan), কম constant। Merge sort stable কিন্তু O(n) extra space লাগে।

  19. Prove merge sort is O(n log n) via recurrence.
    Merge sort-এর O(n log n) প্রমাণ।
    ✨ Show Answer

    T(n) = 2T(n/2) + n। Master Theorem Case 2 → Θ(n log n)। অথবা recursion tree: প্রতিটি level-এ মোট কাজ n, level log n। ∎

  20. Prove there is no comparison sort better than O(n log n).
    Comparison sort-এর নিম্নসীমা প্রমাণ।
    ✨ Show Answer

    Comparison-based sort-এর decision tree-তে ≥ n! leaf থাকতে হবে। Depth ≥ log₂(n!) = Ω(n log n)। তাই worst-case comparison ≥ Ω(n log n)। ∎

  21. Introsort — quicksort + heapsort hybrid.
    Introsort।
    ✨ Show Answer

    Quicksort চালান, কিন্তু recursion depth 2·log n ছাড়ালে সেই subrange heapsort-এ সরান। C++ std::sort-এর basis। Worst-case O(n log n), average quick-এর মতোই দ্রুত।

  22. Timsort — merge + insertion hybrid (Python default).
    Timsort।
    ✨ Show Answer

    Array-কে "run"-এ ভাগ করুন (ছোট অংশ insertion), তারপর sophisticated merge (minrun, galloping)। Real-world data-তে বিশেষভাবে দ্রুত।

  23. Bucket sort for uniformly distributed floats.
    Uniform float-এ bucket sort।
    ✨ Show Answer

    [0, 1)-এ uniform হলে n-টি bucket-এ ভাগ করুন (bucket[floor(x*n)]), প্রতিটি bucket insertion sort, concat। Expected O(n)।

  24. Why is stability useful for multi-key sorting?
    Stability কেন জরুরি?
    ✨ Show Answer

    আগে secondary key-তে sort, তারপর stable sort-এ primary key-তে sort করলে একই primary-র মধ্যে secondary order বজায় থাকে — multi-key sort পরিষ্কারভাবে কাজ করে।

  25. Write a stable sort for a custom struct.
    Custom struct-এ stable sort।
    ✨ Show Answer

    qsort stable নয়। POSIX-এ qsort_r/stable version নেই; manual merge sort ব্যবহার করুন, অথবা compare function-এ original index tie-breaker যোগ করুন।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
SortingArranging elements according to a total order.একটি ক্রম অনুযায়ী element সাজানো।
Comparison SortSorts using only pairwise comparisons — Ω(n log n).শুধু তুলনার মাধ্যমে sort — Ω(n log n)।
Bubble SortRepeatedly swap adjacent out-of-order pairs — O(n²).পাশাপাশি ভুল-ক্রমে থাকা জোড়া বদলে দেওয়া।
Selection SortPick the smallest, move to front, repeat — O(n²).সবচেয়ে ছোট খুঁজে সামনে আনা।
Insertion SortInsert each element into its place in a sorted prefix — O(n²).Sorted অংশে প্রতিটি element সঠিক জায়গায় বসানো।
Merge SortDivide-and-conquer sort — O(n log n), stable.Divide-and-conquer sort — O(n log n), stable।
Quick SortPivot-based partitioning — O(n log n) average, O(n²) worst.Pivot-ভিত্তিক — গড়ে O(n log n)।
Heap SortBuild a heap, repeatedly extract max — O(n log n) in-place.Heap বানিয়ে বারবার max বের করা।
Counting SortLinear-time sort for small integer keys.ছোট integer key-এর জন্য linear-time sort।
Radix SortSort digit by digit — O(n·k).একটি একটি অঙ্ক ধরে sort।
Stable SortEqual-key elements keep their original order.সমান-key element-দের original ক্রম থাকে।
In-place SortUses only O(1) extra memory.O(1) অতিরিক্ত memory-তেই sort।
PivotThe element quicksort partitions around.Quicksort যেটির চারপাশে partition করে।
qsortC standard library's generic sort function.C standard library-র generic sort।

Summary — Module 31

O(n²) sort ছোট বা nearly-sorted data-এ; O(n log n) general workhorse; O(n) linear sort constrained input-এ। Stability ও in-place need অনুযায়ী বেছে নিন।

Next Module → Searching & Divide and Conquer।