
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Quicksort Using Random Pivoting
Quick Sort is a Divide and Conquer algorithm. In this algorithm, we elect a pivot element and then partition the array around the pivot element. The two partitions are such that one part contains elements all lower than the pivot element and the other part contains elements all higher than the pivot element. Similarly, each part is further partitioned around a pivot selected in each part and this process is executed until one single element is reached.
Choosing a Pivot
A pivot can be chosen in an array as follows ?
A random pivot.
Rightmost or leftmost element as pivot.
Median as the pivot.
In this article, we'll be using the first approach to choose a pivot and implement the quicksort algorithm.
Problem Statement
Given an array. Use the quick sort algorithm using random pivoting to sort the array.
Sample Example 1
Input: [3, 1, 7, 2, 10]
Output: [1, 2, 3, 7, 10]
Explanation ? Let, 3 be chosen as the random pivot, swap it with 10 and then set 3 as the pivot and partition the array with 3 as the pivot. After the first partition, the array is [1, 2, 3, 7, 10] with 3 at its sorted position. Then call the function on both the subarrays on the left and right of 3 to sort the rest array.
Sample Example 2
Input: [11, 32, 7, 90, 18, 34]
Output: [7, 11, 18, 32, 34, 90]
Pseudocode
Pseudocode for Swap()
procedure swap (*a, *b) temp = *a *a = *b *b = temp end procedure
Pseudocode for pickRandom()
procedure pickRandom (arr[], start, end) num = Random number between start and end swap arr[num] and arr[end] end procedure
Pseudocode for partition()
procedure partition (arr[], start, end) pickRandom (arr, start, end) pivot = arr[end] i = start for k = start to end - 1 if arr[k] <= pivot swap arr[k] and arr[i] i = i + 1 end if end for swap arr[i] and arr[end] return i end procedure
Pseudocode quickSort()
procedure quickSort (arr[], start, end) if start < end p = pickRandom (arr[], start, end) quickSort (arr[], start, p-1) quickSort (arr[], p+1, end) end if end procedure
Working
Let's take an unsorted array, and call the staaquickSort() function from start to end.
Starting with the pickRandom() function,
Let, num = random number between start and end = 2
Swapping arr[1] and arr[end], we get the following array,
Upon the call of partition() function,
Pivot = arr[end] = 23
Since the pivot is at the end, so algorithm starts from the start and moves towards the end. Taking k from start to end - 1 in a loop and i = start
Now, arr[k] < arr[pivot], so swap arr[k] and arr[i] and i = i + 1.
Now, arr[k] < arr[pivot], so swap arr[k] and arr[i] and i = i + 1.
Now, arr[k] < arr[pivot], so swap arr[k] and arr[i] and i = i + 1.
Now, arr[k] > arr[pivot], so k moves forward.
Now, arr[k] > arr[pivot] and the loop ends.
After the loop ends, swap arr[i] and arr[pivot].
And return i = 3.
Thus, the next quickSort() is called on the array from start to i-1 and then from i+1 to end.
Example: C++ Implementation
In the following program, for sorting an array by quicksort using random pivoting, we first select a random index of the array. The number on this random index is then swapped with the end element of the array. Then the end element is chosen as the pivot. Then the array is partitioned around this pivot and recursively quickSort is called on the partitioned arrays until we are left with one element in each subarray.
#include <bits/stdc++.h> using namespace std; // function to swap values of two variables void swap(int *x, int *y){ int t = *x; *x = *y; *y = t; } // This function picks a random index between start and end and swaps the value at that index to the value at end index. void pickRandom(int arr[], int start, int end){ int num = start + rand() % (end - start + 1); swap(arr[num], arr[end]); } // This function calls the pickRandom() function and then partitions the array into two subarrays int partition(int arr[], int start, int end){ pickRandom(arr, start, end); // End element is chosen as pivot int pivot = arr[end]; int i = start; for (int k = start; k < end; k++){ if (arr[k] <= pivot){ swap(arr[k], arr[i]); i++; } } swap(arr[i], arr[end]); // The array is divided into two sub-parts with the left part having all the elements smaller than the pivot and right part having elements bigger than the pivot. return i; } void quickSort(int arr[], int start, int end){ if (start < end){ // p is the point of partition int p = partition(arr, start, end); // Calling quicksort on left subarray quickSort(arr, start, p - 1); // Calling quicksort on right subarray quickSort(arr, p + 1, end); } } int main(){ int arr[6] = {19, 4, 23, 77, 31, 8}; // Before Sorting cout << "Array before sorting : "; for (int i = 0; i < 6; i++){ cout << arr[i] << " "; } // Applying quick Sort quickSort(arr, 0, 5); // After Sorting cout << "\nArray after sorting : "; for (int i = 0; i < 6; i++){ cout << arr[i] << " "; } return 0; }
Output
Array before sorting : 19 4 23 77 31 8 Array after sorting : 4 8 19 23 31 77
Time Complexity ? Worst Case Complexity = O(n2)
Average(Expected) Case Complexity = O(nlogn).
Space Complexity ? O(nlogn) due to the recursive stack space used.
Conclusion
In conclusion, using quick sort with random pivoting for sorting an array helps improve the average or expected time complexity by O(nlogn) but the worst-case complexity remains O(n2).