javaadvanced

Sorting Algorithms — Quick, Merge, and Heap

Implement classic sorting algorithms in Java: quicksort, mergesort, heapsort, and their time complexity.

java
import java.util.Arrays;
import java.util.Random;

public class SortingAlgorithms {

    // Quick Sort — O(n log n) avg, O(n²) worst
    static void quickSort(int[] arr, int low, int high) {
        if (low >= high) return;
        int pivot = partition(arr, low, high);
        quickSort(arr, low, pivot - 1);
        quickSort(arr, pivot + 1, high);
    }

    private static 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, j);
            }
        }
        swap(arr, i + 1, high);
        return i + 1;
    }

    // Merge Sort — O(n log n) guaranteed
    static void mergeSort(int[] arr, int left, int right) {
        if (left >= right) return;
        int mid = (left + right) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }

    private static void merge(int[] arr, int left, int mid, int right) {
        int[] temp = new int[right - left + 1];
        int i = left, j = mid + 1, k = 0;
        while (i <= mid && j <= right) {
            temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
        }
        while (i <= mid) temp[k++] = arr[i++];
        while (j <= right) temp[k++] = arr[j++];
        System.arraycopy(temp, 0, arr, left, temp.length);
    }

    // Heap Sort — O(n log n)
    static void heapSort(int[] arr) {
        int n = arr.length;
        for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i);
        for (int i = n - 1; i > 0; i--) {
            swap(arr, 0, i);
            heapify(arr, i, 0);
        }
    }

    private static void heapify(int[] arr, int n, int i) {
        int largest = i;
        int left = 2 * i + 1, right = 2 * i + 2;
        if (left < n && arr[left] > arr[largest]) largest = left;
        if (right < n && arr[right] > arr[largest]) largest = right;
        if (largest != i) {
            swap(arr, i, largest);
            heapify(arr, n, largest);
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;
    }

    // Benchmark
    public static void main(String[] args) {
        Random rng = new Random(42);
        int n = 10_000;

        int[] data1 = rng.ints(n, 0, 100_000).toArray();
        int[] data2 = data1.clone();
        int[] data3 = data1.clone();

        long t1 = System.nanoTime();
        quickSort(data1, 0, data1.length - 1);
        System.out.printf("QuickSort: %d ms%n", (System.nanoTime() - t1) / 1_000_000);

        long t2 = System.nanoTime();
        mergeSort(data2, 0, data2.length - 1);
        System.out.printf("MergeSort: %d ms%n", (System.nanoTime() - t2) / 1_000_000);

        long t3 = System.nanoTime();
        heapSort(data3);
        System.out.printf("HeapSort:  %d ms%n", (System.nanoTime() - t3) / 1_000_000);

        System.out.println("Sorted correctly: " +
            (Arrays.equals(data1, data2) && Arrays.equals(data2, data3)));
    }
}

Use Cases

  • Understanding sorting algorithm trade-offs
  • Custom sorting for specialized data
  • Interview preparation for algorithm questions

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.