Implementing Selection, Heap, and Bubble Sort Algorithms in C

Introduction to Sorting Algorithms

Sorting is the fundamental process of rearranging a collection of data into a specific sequence, typically ascending or descending order based on the values of the elements. In computer science, various algorithms exist to achieve this, each with unique characteristics regarding efficiency and memory usage. This article focuses on the implementation and analysis of three specific comparison-based sorting algorithms: Selection Sort, Heap Sort, and Bubble Sort.

Selection Sort

Selection sort operates by dividing the input list into two parts: a sorted sublist at the left end and an unsorted sublist at the right end. Initially, the sorted sublist is empty. The algorithm proceeds by iterating through the unsorted sublist to find the minimum and maximum values. The minimum value is swapped with the leftmost unsorted element, and the maximum value is swapped with the rightmost unsorted element. This bidirectional approach reduces the number of passes required compared to the standard single-direction selection sort.

Algorithm Implementation:

#include <stdio.h>

void swap(int* x, int* y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

void bidirectionalSelectionSort(int* data, int size) {
    int begin = 0;
    int end = size - 1;

    while (begin < end) {
        int minIndex = begin;
        int maxIndex = begin;

        // Iterate through the unsorted range to find min and max
        for (int i = begin + 1; i <= end; i++) {
            if (data[i] > data[maxIndex]) {
                maxIndex = i;
            }
            if (data[i] < data[minIndex]) {
                minIndex = i;
            }
        }

        // Place the minimum element at the correct position
        if (minIndex != begin) {
            swap(&data[begin], &data[minIndex]);
        }

        // Special handling: if the max element was at 'begin',
        // it was moved to 'minIndex' during the previous swap
        if (maxIndex == begin) {
            maxIndex = minIndex;
        }

        // Place the maximum element at the correct position
        if (maxIndex != end) {
            swap(&data[end], &data[maxIndex]);
        }

        begin++;
        end--;
    }
}

Algorithm Analysis:

  • Time Complexity: O(N²). The algorithm involves nested loops; regardless of the input order, it scans the remaining unsorted elements to find min/max values.
  • Space Complexity: O(1). It performs sorting in place, requiring only a constant amount of additional memory for variables.
  • Stability: Unstable. Since elements can jump long distances (e.g., swapping a non-adjacent maximum), the relative order of equal elements may change.

Heap Sort

Heap sort utilizes a binary heap data structure. To sort data in ascending order, the algorithm first constructs a Max Heap. In a Max Heap, the parent node is always greater than its children. Once the heap is built, the largest element (the root) is swapped with the last element of the array. The heap size is then reduced by one, and the "heapify" process is called on the new root to restore the heap property. This cycle repeats until the entire array is sorted.

Algorithm Implementation:

// Maintain the max-heap property for a subtree rooted at index 'root'
void heapify(int* arr, int size, int root) {
    int largest = root;
    int leftChild = 2 * root + 1;
    int rightChild = 2 * root + 2;

    // Check if left child exists and is greater than root
    if (leftChild < size && arr[leftChild] > arr[largest]) {
        largest = leftChild;
    }

    // Check if right child exists and is greater than largest so far
    if (rightChild < size && arr[rightChild] > arr[largest]) {
        largest = rightChild;
    }

    // If largest is not root, swap and continue heapifying
    if (largest != root) {
        swap(&arr[root], &arr[largest]);
        heapify(arr, size, largest);
    }
}

void heapSort(int* arr, int size) {
    // Build the max heap (rearrange array)
    for (int i = size / 2 - 1; i >= 0; i--) {
        heapify(arr, size, i);
    }

    // Extract elements from heap one by one
    for (int i = size - 1; i > 0; i--) {
        // Move current root (maximum) to end
        swap(&arr[0], &arr[i]);
        
        // Call max heapify on the reduced heap
        heapify(arr, i, 0);
    }
}

Algorithm Analysis:

  • Time Complexity: O(N log N). Building the heap takes O(N), and each of the N-1 extracsions takes O(log N) time.
  • Space Complexity: O(1). The standard implementation works in place.
  • Stability: Unstable. The swapping of elements across the heap structure during extraction disrupts the original relative order of duplicate keys.

Bubble Sort

Bubble sort is a simple comparison-based algorithm. It repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. This pass is repeated until the list is sorted. The name "bubble sort" comes from the way smaller or larger elements "bubble" to the top of the list (depending on the order) with each iteration. An optimization is added where a flag checks if any swaps occurred; if no swaps occur during a pass, the list is already sorted, and the algorithm can terminate early.

Algorithm Implementation:

void optimizedBubbleSort(int* arr, int n) {
    for (int i = 0; i < n - 1; i++) {
        int swapped = 0;
        
        // Last i elements are already in place
        for (int j = 0; j < n - i - 1; j++) {
            // Compare adjacent elements
            if (arr[j] > arr[j + 1]) {
                swap(&arr[j], &arr[j + 1]);
                swapped = 1;
            }
        }

        // If no two elements were swapped by inner loop, break
        if (swapped == 0) {
            break;
        }
    }
}

Algorithm Analysis:

  • Time Complexity: O(N²) in the worst and average cases. In the best case (already sorted array), with the optimization flag, the time complexity reduces to O(N).
  • Space Complexity: O(1). It operates in place.
  • Stability: Stable. Since it only swaps adjacent elements when they are strictly unequal (or strictly greater for ascending order), it preserves the relative order of equal elements.

Posted on Sun, 21 Jun 2026 17:23:29 +0000 by anothersystem