Implementing Quick Sort in Java

Quick Sort is a highly efficient, comparison-based sorting algorithm that uses the divide-and-conquer strategy. It selects a pivot element, partitions the array into elements smaller than the pivot and elements larger than the pivot, then recursively sorts each partition. Its average-case time complexity is O(n log n), making it one of the fastest general-purpose sorting algorithms in practice.

How Quick Sort Works

  1. Choose the first element of the current subarray as the pivot.
  2. Create a temporary array: place all elements smaller than the pivot first, then the pivot, then all elements larger.
  3. Copy the temporary array back to the original positions.
  4. Recursively apply the same process to the left subarray (before pivot) and the right subarray (after pivot).
  5. Base case: subarrays of size 0 or 1 are already sorted.

Java Program: Quick Sort

import java.io.*;

// Quick Sort implementation using a pivot-based partition strategy
class QuickSort {
    int[] array;    // The array to be sorted
    int lowerBound; // Starting index (0-based)
    int upperBound; // Ending index (array.length - 1)
    int size;       // Total number of elements

    public QuickSort(int[] inputArray) {
        array = inputArray;
        lowerBound = 0;
        size = array.length;
        upperBound = array.length - 1;
    }

    // Public entry point: starts the sort across the full array
    public void sort() {
        sortPartition(lowerBound, upperBound);
    }

    // Recursively sorts the subarray between indices lb and ub
    private void sortPartition(int lb, int ub) {
        if (lb >= ub) return;  // Base case: nothing to sort

        int[] temp = new int[size];
        int tempIndex = lb;
        int pivot = array[lb];  // Choose first element as pivot

        if (lb == ub) {
            temp[lb] = pivot;
            return;
        }

        // Phase 1: elements smaller than pivot go to left side of temp
        for (int i = lb; i <= ub; i++) {
            if (pivot > array[i]) {
                temp[tempIndex] = array[i];
                tempIndex++;
            }
        }

        // Phase 2: pivot goes in its correct sorted position
        int pivotIndex = tempIndex;
        temp[tempIndex] = pivot;
        tempIndex++;

        // Phase 3: elements larger than pivot go to right side
        for (int i = lb; i <= ub; i++) {
            if (pivot < array[i]) {
                temp[tempIndex] = array[i];
                tempIndex++;
            }
        }

        // Copy rearranged section back into original array
        for (int i = lb; i <= ub; i++) {
            array[i] = temp[i];
        }

        // Recursively sort left and right partitions
        if (lb < ub) {
            sortPartition(lb, pivotIndex - 1);
            sortPartition(pivotIndex + 1, ub);
        }
    }

    // Prints all elements of the array separated by spaces
    public void display() {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
}

public class QuickSortDemo {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Enter the size of array: ");
        int size = Integer.parseInt(reader.readLine());

        int[] array = new int[size];
        System.out.println("Enter " + size + " elements (one per line):");
        for (int i = 0; i < size; i++) {
            array[i] = Integer.parseInt(reader.readLine());
        }

        QuickSort sorter = new QuickSort(array);

        System.out.print("Array before sort: ");
        sorter.display();

        sorter.sort();

        System.out.print("Array after sort:  ");
        sorter.display();
    }
}

How the Code Works

  1. QuickSort class — Wraps the array and exposes a sort() method. Internally uses sortPartition(lb, ub) which operates on any subrange.
  2. Pivot selection — The first element (array[lb]) is chosen as the pivot. Simple but can degrade to O(n²) on already-sorted input.
  3. Three-phase pass — Elements smaller than pivot go left in temp, the pivot occupies its exact sorted position, and elements larger fill the right.
  4. Recursive calls — After partition, the algorithm recurses on [lb, pivotIndex-1] and [pivotIndex+1, ub] independently.
  5. Base case — When lb >= ub, the subarray has 0 or 1 elements and is trivially sorted; recursion stops.

Sample Output

Enter the size of array: 7
Enter 7 elements (one per line):
15
32
45
25
34
29
14
Array before sort: 15 32 45 25 34 29 14
Array after sort:  14 15 25 29 32 34 45

Output Explanation

Input: [15, 32, 45, 25, 34, 29, 14]. Pivot = 15.

  • First partition — Elements less than 15: [14]. Pivot: [15]. Elements greater: [32, 45, 25, 34, 29].
  • Left partition — [14] is a single element; already sorted.
  • Right partition — [32, 45, 25, 34, 29] is recursively sorted.
  • Final result — [14, 15, 25, 29, 32, 34, 45].

See Also

Conclusion

Quick Sort is one of the most widely used sorting algorithms because of its excellent average-case performance and in-place sorting capability. The implementation here uses a simple first-element pivot strategy. In production, pivot selection is often improved (e.g., median-of-three or random pivot) to avoid worst-case O(n²) behaviour on already-sorted input. Java’s own Arrays.sort() uses a dual-pivot quicksort for primitive types.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.