Quicksort algorithm in Java with Example

Quicksort algorithm is one of the most used sorting algorithm, especially to sort large lists/arrays. Quicksort is a divide and conquer algorithm, which means original array is divided into two arrays, each of them is sorted individually and then sorted output is merged to produce the sorted array.

 On the average, it has O(n log n) complexity, making quicksort suitable for sorting big data volumes.

In more standard words, quicksort algorithm repeatedly divides an un-sorted section into a lower order sub-section and a higher order sub-section by comparing to a pivot element. For more additional info Java Online Course

At the end of recursion, we get sorted array. Please note that the quicksort can be implemented to sort “in-place”.

This means that the sorting takes place in the array and that no additional array need to be created.

There are many different versions of quickSort that pick pivot in different ways.

  1. Always pick first element as pivot.
  2. Always pick last element as pivot (implemented below)
  3. Pick a random element as pivot.
  4. Pick median as pivot.

The key process in quickSort is partition(). Target of partitions is, given an array and an element x of array as pivot, put x at its correct position in sorted array and put all smaller elements (smaller than x) before x, and put all greater elements (greater than x) after x. All this should be done in linear time. For more info Java Online Classes

The algorithm processes the array in the following way.

  1. Set the first index of the array to left and loc variable. Set the last index of the array to right variable. i.e. left = 0, loc = 0, en d = n – 1, where n is the length of the array.
  2. Start from the right of the array and scan the complete array from right to beginning comparing each element of the array with the element pointed by loc.
    1. Ensure that, a[loc] is less than a[right].
    2. If this is the case, then continue with the comparison until right becomes equal to the loc. If a[loc] > a[right], then swap the two values. And go to step
    3. Set, loc = right
  3. start from element pointed by left and compare each element in its way with the element pointed by the variable loc. Ensure that a[loc] > a[left]
    1. if this is the case, then continue with the comparison until loc becomes equal to left.
    2. [loc] < a[right], then swap the two values and go to step 2.
    3. Set, loc = left.

Algorithm:

PARTITION (ARR, BEG, END, LOC)

  • Step 1: [INITIALIZE] SET LEFT = BEG, RIGHT = END, LOC = BEG, FLAG =
  • Step 2: Repeat Steps 3 to 6 while FLAG =
  • Step 3: Repeat while ARR[LOC] <=ARR[RIGHT]
    AND LOC != RIGHT
    SET RIGHT = RIGHT – 1
    [END OF LOOP]
  • Step 4: IF LOC = RIGHT
    SET FLAG = 1
    ELSE IF ARR[LOC] > ARR[RIGHT]
    SWAP ARR[LOC] with ARR[RIGHT]
    SET LOC = RIGHT
    [END OF IF]
  • Step 5: IF FLAG = 0
    Repeat while ARR[LOC] >= ARR[LEFT] AND LOC != LEFT
    SET LEFT = LEFT + 1
    [END OF LOOP]
  • Step 6:IF LOC = LEFT
    SET FLAG = 1
    ELSE IF ARR[LOC] < ARR[LEFT]
    SWAP ARR[LOC] with ARR[LEFT]
    SET LOC = LEFT
    [END OF IF]
    [END OF IF]
  • Step 7: [END OF LOOP]
  • Step 8: END

QUICK_SORT (ARR, BEG, END)

  • Step 1: IF (BEG < END)
    CALL PARTITION (ARR, BEG, END, LOC)
    CALL QUICKSORT(ARR, BEG, LOC – 1)
    CALL QUICKSORT(ARR, LOC + 1, END)
    [END OF IF]
  • Step 2: END

Algorithm Analysis:

Time Complexity:

In the best case, the algorithm will divide the list into two equal size sub-lists. So, the first iteration of the full n-sized list needs O(n). Sorting the remaining two sub-lists with n/2 elements takes 2*O(n/2) each. As a result, the QuickSort algorithm has the complexity of O(n log n).

In the worst case, the algorithm will select only one element in each iteration, so O(n) + O(n-1) + … + O(1), which is equal to O(n2).

On the average QuickSort has O(n log n) complexity, making it suitable for big data volumes. For programming skills on Java Certification Course

QuickSort vs MergeSort:

Let’s discuss in which cases we should choose QuickSort over MergeSort.

Although both Quicksort and Mergesort have an average time complexity of O(n log n), Quicksort is the preferred algorithm, as it has an O(log(n)) space complexity. Mergesort, on the other hand, requires O(n) extra storage, which makes it quite expensive for arrays.

Quicksort requires to access different indices for its operations, but this access is not directly possible in linked lists, as there are no continuous blocks; therefore to access an element we have to iterate through each node from the beginning of the linked list. Also, Mergesort is implemented without extra space for LinkedLists.

In such case, overhead increases for Quicksort and Mergesort is generally preferred.

Example:

public class QuickSort {
 
    public static void main(String[] args) {
        int[] arr = {4, 5, 1, 2, 3, 3};
        quickSort(arr, 0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
 
    public static void quickSort(int[] arr, int start, int end){
 
        int partition = partition(arr, start, end);
 
        if(partition-1>start) {
            quickSort(arr, start, partition - 1);
        }
        if(partition+1<end) {
            quickSort(arr, partition + 1, end);
        }
    }
 
    public static int partition(int[] arr, int start, int end){
        int pivot = arr[end];
 
        for(int i=start; i<end; i++){
            if(arr[i]<pivot){
                int temp= arr[start];
                arr[start]=arr[i];
                arr[i]=temp;
                start++;
            }
        }
 
        int temp = arr[start];
        arr[start] = pivot;
        arr[end] = temp;
 
        return start;
    }
}

public class QuickSort {
	public static void main(String[] args) {
		int[] x = { 9, 2, 4, 7, 3, 7, 10 };
		System.out.println(Arrays.toString(x));
 
		int low = 0;
		int high = x.length - 1;
 
		quickSort(x, low, high);
		System.out.println(Arrays.toString(x));
	}
 
	public static void quickSort(int[] arr, int low, int high) {
		if (arr == null || arr.length == 0)
			return;
 
		if (low >= high)
			return;
 
		// pick the pivot
		int middle = low + (high - low) / 2;
		int pivot = arr[middle];
 
		// make left < pivot and right > pivot
		int i = low, j = high;
		while (i <= j) {
			while (arr[i] < pivot) {
				i++;
			}
 
			while (arr[j] > pivot) {
				j--;
			}
 
			if (i <= j) {
				int temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
				i++;
				j--;
			}
		}
 
		// recursively sort two sub parts
		if (low < j)
			quickSort(arr, low, j);
 
		if (high > i)
			quickSort(arr, i, high);
	}
}

To get in-depth knowledge, enroll for a live free demo on Java Online Training

Leave a comment

Design a site like this with WordPress.com
Get started