Quickselect is a selection algorithm to find the k-th smallest element in an unordered list. It is related to the quick sort sorting algorithm.
Examples:
Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 3
Output: 7
Input: arr[] = {7, 10, 4, 3, 20, 15}
k = 4
Output: 10
The algorithm is similar to QuickSort. The difference is, instead of recurring for both sides (after finding pivot), it recurs only for the part that contains the k-th smallest element. The logic is simple, if index of the partitioned element is more than k, then we recur for the left part. If index is the same as k, we have found the k-th smallest element and we return. If index is less than k, then we recur for the right part. This reduces the expected complexity from O(n log n) to O(n), with a worst-case of O(n^2).
function quickSelect(list, left, right, k)
if left = right
return list[left]
Select a pivotIndex between left and right
pivotIndex := partition(list, left, right,
pivotIndex)
if k = pivotIndex
return list[k]
else if k < pivotIndex
right := pivotIndex - 1
else
left := pivotIndex + 1
C++14
#include <bits/stdc++.h>
using namespace std;
// Standard partition process of QuickSort.
// It considers the last element as pivot
// and moves all smaller elements to the left of
// it and greater elements to the right.
int partition(vector<int>& arr, int l, int r) {
int x = arr[r], i = l;
for (int j = l; j <= r - 1; j++) {
if (arr[j] <= x) {
swap(arr[i], arr[j]);
i++;
}
}
swap(arr[i], arr[r]);
return i;
}
// This function returns the k-th smallest
// element in arr[l..r] using QuickSort-based method.
// ASSUMPTION: ALL ELEMENTS IN ARR[] ARE DISTINCT.
int kthSmallest(vector<int>& arr, int l, int r, int k) {
// If k is smaller than the number of elements
// in the array.
if (k > 0 && k <= r - l + 1) {
// Partition the array around the last
// element and get the position of the pivot
// element in the sorted array.
int index = partition(arr, l, r);
// If position is the same as k.
if (index - l == k - 1)
return arr[index];
// If position is more, recur for the left subarray.
if (index - l > k - 1)
return kthSmallest(arr, l, index - 1, k);
// Else recur for the right subarray.
return kthSmallest(arr, index + 1, r,
k - index + l - 1);
}
// If k is more than the number of elements in the array.
return INT_MAX;
}
// Driver program to test the above methods.
int main() {
vector<int> arr = {10, 4, 5, 8, 6, 11, 26};
int n = arr.size();
int k = 3;
cout << "K-th smallest element is "
<< kthSmallest(arr, 0, n - 1, k);
return 0;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// Function to swap two elements
void swap(int *a, int *b);
// Standard partition process of QuickSort.
// It considers the last element as pivot
// and moves all smaller elements to the left of
// it and greater elements to the right.
int partition(int arr[], int l, int r) {
int x = arr[r], i = l;
for (int j = l; j <= r - 1; j++) {
if (arr[j] <= x) {
swap(&arr[i], &arr[j]);
i++;
}
}
swap(&arr[i], &arr[r]);
return i;
}
// This function returns the k-th smallest
// element in arr[l..r] using QuickSort-based method.
// ASSUMPTION: ALL ELEMENTS IN ARR[] ARE DISTINCT.
int kthSmallest(int arr[], int l, int r, int k) {
// If k is smaller than the number of elements
// in the array.
if (k > 0 && k <= r - l + 1) {
// Partition the array around the last
// element and get the position of the pivot
// element in the sorted array.
int index = partition(arr, l, r);
// If position is the same as k.
if (index - l == k - 1)
return arr[index];
// If position is more, recur for the left subarray.
if (index - l > k - 1)
return kthSmallest(arr, l, index - 1, k);
// Else recur for the right subarray.
return kthSmallest(arr, index + 1, r,
k - index + l - 1);
}
// If k is more than the number of
// elements in the array.
return INT_MAX;
}
// Function to swap two elements
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// Driver program to test the above methods.
int main() {
int arr[] = {10, 4, 5, 8, 6, 11, 26};
int n = sizeof(arr) / sizeof(arr[0]);
int k = 3;
printf("K-th smallest element is %d\n",
kthSmallest(arr, 0, n - 1, k));
return 0;
}
Java
// Java program of Quick Select
import java.util.Arrays;
class GFG {
// partition function similar to quick sort
// Considers last element as pivot and adds
// elements with less value to the left and
// high value to the right and also changes
// the pivot position to its respective position
// in the final array.
public static int partition(int[] arr, int low,
int high)
{
int pivot = arr[high], pivotloc = low;
for (int i = low; i <= high; i++) {
// inserting elements of less value
// to the left of the pivot location
if (arr[i] < pivot) {
int temp = arr[i];
arr[i] = arr[pivotloc];
arr[pivotloc] = temp;
pivotloc++;
}
}
// swapping pivot to the final pivot location
int temp = arr[high];
arr[high] = arr[pivotloc];
arr[pivotloc] = temp;
return pivotloc;
}
// finds the kth position (of the sorted array)
// in a given unsorted array i.e this function
// can be used to find both kth largest and
// kth smallest element in the array.
// ASSUMPTION: all elements in arr[] are distinct
public static int kthSmallest(int[] arr, int low,
int high, int k)
{
// find the partition
int partition = partition(arr, low, high);
// if partition value is equal to the kth position,
// return value at k.
if (partition == k - 1)
return arr[partition];
// if partition value is less than kth position,
// search right side of the array.
else if (partition < k - 1)
return kthSmallest(arr, partition + 1, high, k);
// if partition value is more than kth position,
// search left side of the array.
else
return kthSmallest(arr, low, partition - 1, k);
}
// Driver Code
public static void main(String[] args)
{
int[] array = new int[] { 10, 4, 5, 8, 6, 11, 26 };
int[] arraycopy
= new int[] { 10, 4, 5, 8, 6, 11, 26 };
int kPosition = 3;
int length = array.length;
if (kPosition > length) {
System.out.println("Index out of bound");
}
else {
// find kth smallest value
System.out.println(
"K-th smallest element in array : "
+ kthSmallest(arraycopy, 0, length - 1,
kPosition));
}
}
}
// This code is contributed by Saiteja Pamulapati
Python
# Python3 program of Quick Select
# Standard partition process of QuickSort().
# It considers the last element as pivot
# and moves all smaller element to left of
# it and greater elements to right
def partition(arr, l, r):
x = arr[r]
i = l
for j in range(l, r):
if arr[j] <= x:
arr[i], arr[j] = arr[j], arr[i]
i += 1
arr[i], arr[r] = arr[r], arr[i]
return i
# finds the kth position (of the sorted array)
# in a given unsorted array i.e this function
# can be used to find both kth largest and
# kth smallest element in the array.
# ASSUMPTION: all elements in arr[] are distinct
def kthSmallest(arr, l, r, k):
# if k is smaller than number of
# elements in array
if (k > 0 and k <= r - l + 1):
# Partition the array around last
# element and get position of pivot
# element in sorted array
index = partition(arr, l, r)
# if position is same as k
if (index - l == k - 1):
return arr[index]
# If position is more, recur
# for left subarray
if (index - l > k - 1):
return kthSmallest(arr, l, index - 1, k)
# Else recur for right subarray
return kthSmallest(arr, index + 1, r,
k - index + l - 1)
print("Index out of bound")
# Driver Code
arr = [ 10, 4, 5, 8, 6, 11, 26 ]
n = len(arr)
k = 3
print("K-th smallest element is ", end = "")
print(kthSmallest(arr, 0, n - 1, k))
# This code is contributed by Muskan Kalra.
C#
// C# program of Quick Select
using System;
class GFG
{
// partition function similar to quick sort
// Considers last element as pivot and adds
// elements with less value to the left and
// high value to the right and also changes
// the pivot position to its respective position
// in the readonly array.
static int partitions(int []arr,int low, int high)
{
int pivot = arr[high], pivotloc = low, temp;
for (int i = low; i <= high; i++)
{
// inserting elements of less value
// to the left of the pivot location
if(arr[i] < pivot)
{
temp = arr[i];
arr[i] = arr[pivotloc];
arr[pivotloc] = temp;
pivotloc++;
}
}
// swapping pivot to the readonly pivot location
temp = arr[high];
arr[high] = arr[pivotloc];
arr[pivotloc] = temp;
return pivotloc;
}
// finds the kth position (of the sorted array)
// in a given unsorted array i.e this function
// can be used to find both kth largest and
// kth smallest element in the array.
// ASSUMPTION: all elements in []arr are distinct
static int kthSmallest(int[] arr, int low,
int high, int k)
{
// find the partition
int partition = partitions(arr,low,high);
// if partition value is equal to the kth position,
// return value at k.
if(partition == k)
return arr[partition];
// if partition value is less than kth position,
// search right side of the array.
else if(partition < k )
return kthSmallest(arr, partition + 1, high, k );
// if partition value is more than kth position,
// search left side of the array.
else
return kthSmallest(arr, low, partition - 1, k );
}
// Driver Code
public static void Main(String[] args)
{
int[] array = {10, 4, 5, 8, 6, 11, 26};
int[] arraycopy = {10, 4, 5, 8, 6, 11, 26};
int kPosition = 3;
int length = array.Length;
if(kPosition > length)
{
Console.WriteLine("Index out of bound");
}
else
{
// find kth smallest value
Console.WriteLine("K-th smallest element in array : " +
kthSmallest(arraycopy, 0, length - 1,
kPosition - 1));
}
}
}
// This code is contributed by 29AjayKumar
JavaScript
<script>
// Javascript program of Quick Select
// partition function similar to quick sort
// Considers last element as pivot and adds
// elements with less value to the left and
// high value to the right and also changes
// the pivot position to its respective position
// in the final array.
function _partition(arr, low, high)
{
let pivot = arr[high], pivotloc = low;
for (let i = low; i <= high; i++)
{
// inserting elements of less value
// to the left of the pivot location
if (arr[i] < pivot)
{
let temp = arr[i];
arr[i] = arr[pivotloc];
arr[pivotloc] = temp;
pivotloc++;
}
}
// swapping pivot to the final pivot location
let temp = arr[high];
arr[high] = arr[pivotloc];
arr[pivotloc] = temp;
return pivotloc;
}
// finds the kth position (of the sorted array)
// in a given unsorted array i.e this function
// can be used to find both kth largest and
// kth smallest element in the array.
// ASSUMPTION: all elements in arr[] are distinct
function kthSmallest(arr, low, high, k)
{
// find the partition
let partition = _partition(arr, low, high);
// if partition value is equal to the kth position,
// return value at k.
if (partition == k - 1)
return arr[partition];
// if partition value is less than kth position,
// search right side of the array.
else if (partition < k - 1)
return kthSmallest(arr, partition + 1, high, k);
// if partition value is more than kth position,
// search left side of the array.
else
return kthSmallest(arr, low, partition - 1, k);
}
// Driver Code
let array = [ 10, 4, 5, 8, 6, 11, 26];
let arraycopy = [10, 4, 5, 8, 6, 11, 26 ];
let kPosition = 3;
let length = array.length;
if (kPosition > length) {
document.write("Index out of bound<br>");
}
else
{
// find kth smallest value
document.write(
"K-th smallest element in array : "
+ kthSmallest(arraycopy, 0, length - 1,
kPosition)+"<br>");
}
// This code is contributed by rag2127
</script>
Output:
K-th smallest element is 6
Important Points:
- Like quicksort, it is fast in practice, but has poor worst-case performance. It is used in
- The partition process is same as QuickSort, only recursive code differs.
- There exists an algorithm that finds k-th smallest element in O(n) in worst case, but QuickSelect performs better on average.
Time Complexity : O(n^2) in the worst case, but on average works in O(n Log n) time and performs better than priority queue based algorithm.
Auxiliary Space : O(n) for recursion call stack in worst case. On average : O(Log n)
Related C++ function : std::nth_element in C++
Similar Reads
Quick Select in Python Quick Select is an efficient algorithm for finding the k-th smallest (or largest) element in an unordered list. It is a variation of the QuickSort algorithm and works by repeatedly partitioning the input array around a pivot element until the desired element is found. Quick Select Algorithm:Quick Se
4 min read
Searching Algorithms Searching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
3 min read
Preparata Algorithm Preparata's algorithm is a recursive Divide and Conquer Algorithm where the rank of each input key is computed and the keys are outputted according to their ranks. C++ m[i, j] := M[i, j] for 1 <= i, j <= n in parallel; for r : = 1 to logn do { Step 1. In parallel set q[i, j, k] := m[i, j] + m[
14 min read
Improvement on the Quick Sort Algorithm Prerequisite: QuickSort Algorithm The quicksort algorithm discussed in this article can take O(N2) time in the worst case. Hence, certain variations are needed which can efficiently partition the array and rearrange the elements around the pivot. Single Pivot Partitioning: In single pivot partitioni
6 min read
Divide and Conquer Algorithm Divide and Conquer algorithm is a problem-solving strategy that involves. Divide : Break the given problem into smaller non-overlapping problems.Conquer : Solve Smaller ProblemsCombine : Use the Solutions of Smaller Problems to find the overall result.Examples of Divide and Conquer are Merge Sort, Q
1 min read