
Quick sort
Random shuffle is a key for good performance in the quick sort algorithm because it guarantees that the worst case isn't gonna happen(rarely happens).
Tuned quicksort for primitive types;
Worst Case: Array already sorted takes O(n^2) - imp slide # 18
Randomized Quick Sort - for Duplicate values takes quadratic time
#include <iostream>
#include <random>
using namespace std;
int partition(int *arr, int s, int e)
{
int i = s, j = e + 1;
while (true)
{
// find item on left to swap
while (arr[++i] < arr[s]) {
if (i == e) break;
}
// find item on right to swap
while (arr[s] < arr[--j]) {
if (j == s) break;
}
// check if pointers cross
if (i >= j) break;
swap(arr[i], arr[j]);
}
swap(arr[s], arr[j]); // swap with partitioning item
return j;
}
void shuffling(int *arr, int n) {
for (int i = 0; i < n; i++) {
std::random_device rd;
std::uniform_int_distribution<int> key(0, i);
swap(arr[i], arr[key(rd)]);
}
}
void quickSort(int *arr, int s, int e) {
if (s >= e) return;
int j = partition(arr, s, e);
quickSort(arr, s, j - 1);
quickSort(arr, j + 1, e);
}
int main() {
int arr[] = {3, 2, 5, 1, 4};
shuffling(arr, 5); // shuffle needed for performance guarantee
quickSort(arr, 0, 4);
for (int i = 0; i < 5; i++)
cout << arr[i] << " ";
}

Duplicate keys: Dijkstra 3 - Way partitioning Quick Sort - handle duplicate values in o(nlgn)

v = arr[lo] = 'P'


#include <iostream>
#include <random>
using namespace std;
void shuffling(int *arr, int n)
{
for (int i = 0; i < n; i++) {
std::random_device rd;
std::uniform_int_distribution<int> key(0, i);
swap(arr[i], arr[key(rd)]);
}
}
void quickSort(int *arr, int s, int e) {
if (s >= e) return;
int it = s, gt = e, i = s;
int v = arr[s];
while (i <= gt) {
if (arr[i] < v) swap(arr[i++], arr[it++]);
else if (arr[i] > v) swap(arr[i], arr[gt--]);
else i++;
}
quickSort(arr, s, it - 1);
quickSort(arr, gt + 1, e);
}
int main() {
int arr[] = {1, 3, 3, 1, 4, 3};
shuffling(arr, 6); // shuffle needed for performance guarantee
quickSort(arr, 0, 5);
for (int i = 0; i < 6; i++)
cout << arr[i] << " ";
}
Bottom line. Randomized quicksort with 3-way partitioning reduces running time from linearithmic (nlgn) to linear in a broad class of applications.

Time Complexity
Best Case: O(nlogn)
Average Case: O(nlogn)
Worst Case: O(n2) (low probability due to randomization)
Randomization helps ensure that the algorithm performs closer to the average case most of the time, providing reliable performance in practical scenarios.
Find kth-Smallest Element using the QuickSelect Algorithm
Description: Implement a program to find the kth smallest element in an unsorted array efficiently using the QuickSelect algorithm, a quicksort algorithm variation. This algorithm allows for finding the kth smallest element in linear time complexity on average.

Last updated