< Nafees />
github
  • Assignments - DSA
  • Long Integer Operations
  • OOP
    • Introduction
    • Implementation
  • Sorting Algorithms
    • Selection Sort
    • Bubble Sort
    • Insertion Sort
    • Shell Sort
    • Shuffle
    • Merge Sort
    • Convex Hull
    • Quick sort
    • System Sort
    • Heap-Sort
  • Binary Search
  • Binary Search By Recursion
  • Two-Pointer
  • String
  • LeetCode 75
    • Array/String
    • Hash Map
    • BST
    • Binary Search
  • Top Interview 150
    • Linked-List
  • Leetcode Programming Skill
    • Math
  • Leetcode 75
  • 🤡Leet Code Extra
  • Arrays
    • 1-D Array
    • 2-D Arrays
  • 👨‍🍳Basic Math - Codechef
  • ☠️Recursion
  • 😁Public Member Functions
    • Strings Functions
  • 👾Linked List
    • What's Linked List & Implementation?
      • Singly Linked List
      • Doubly Linked List
    • Problems
  • 📚Stack
    • What's Stack & Implementation?
      • Stack Using Array
      • Stack using LL
    • Problems
  • 🏧Queue
    • What's Queue & Implementation?
      • Simple Queue
      • Queue using LL
      • Circular Queue
      • Deque using Linked List
      • STL Deque
    • Problems
  • 🏧Priority Queue
    • What's Priority Queue & Implementation
      • OrderedArrayMaxPQ.Java
      • Maximum-Oriented PQ using Binary Heap
      • Minimum-Oriented PQ using Binary Heap
    • Problems
  • 🗓️Hash Table
    • What's Hash Table & Implementation
      • ST - Seperate Chaining
      • ST - Linear Probing
    • Problems
  • 🎴Symbol Table
    • What's Symbol Table and implementation
      • ST Using Binary search (ordered array)
      • ST Using Binary Search Tree
      • ST Using Left-Leaning Red-Black Tree
      • ST Using Hash Table
    • Problems
  • 🔗Union-Find (Dynamic Connectivity problem)
    • What is a Union Find Data Structure?
    • Implementation
  • 🎋Binary Tree
    • What's Binary Tree & Implementation?
      • Traversal
      • Red-Black BST
  • 🌴Trie
    • What's Trie & Implementation?
    • Problems
  • 😎Project
    • Expression Evaluation
Powered by GitBook
On this page
  • Time Complexity
  • Find kth-Smallest Element using the QuickSelect Algorithm

Was this helpful?

  1. Sorting Algorithms

Quick sort

PreviousConvex HullNextSystem Sort

Last updated 10 months ago

Was this helpful?

  • 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(nlog⁡n)

  • Average Case: O(nlog⁡n)

  • 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.

#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)]);
     }
}

int quickSelect(int *arr, int n, int k)
{
     k -= 1;
     shuffling(arr, n); // shuffle needed for performance guarantee
     int s = 0, e = n - 1;
     while (s < e)
     {
          int j = partition(arr, s, e);
          if (j > k)
               e = j - 1;
          else if (j < k)
               s = j + 1;
          else
               return arr[k];
     }
     return arr[k];
}

int main()
{
     int arr[] = {6, 3, 1, 6, 0, 4, 8};
     int size = 7;
     cout << quickSelect(arr, size, 5) << endl;
}
4MB
Quicksort.pdf
pdf
Page cover image