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;
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;
}
int kthSmallest( int arr[], int l, int r, int k)
{
if (k > 0 && k <= r - l + 1) {
int index = partition(arr, l, r);
if (index - l == k - 1)
return arr[index];
if (index - l > k - 1)
return kthSmallest(arr, l, index - 1, k);
return kthSmallest(arr, index + 1, r,
k - index + l - 1);
}
return INT_MAX;
}
int main()
{
int arr[] = { 10, 4, 5, 8, 6, 11, 26 };
int n = sizeof (arr) / sizeof (arr[0]);
int k = 3;
cout << "K-th smallest element is "
<< kthSmallest(arr, 0, n - 1, k);
return 0;
}
|
Java
import java.util.Arrays;
class GFG {
public static int partition( int [] arr, int low,
int high)
{
int pivot = arr[high], pivotloc = low;
for ( int i = low; i <= high; i++) {
if (arr[i] < pivot) {
int temp = arr[i];
arr[i] = arr[pivotloc];
arr[pivotloc] = temp;
pivotloc++;
}
}
int temp = arr[high];
arr[high] = arr[pivotloc];
arr[pivotloc] = temp;
return pivotloc;
}
public static int kthSmallest( int [] arr, int low,
int high, int k)
{
int partition = partition(arr, low, high);
if (partition == k - 1 )
return arr[partition];
else if (partition < k - 1 )
return kthSmallest(arr, partition + 1 , high, k);
else
return kthSmallest(arr, low, partition - 1 , k);
}
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 {
System.out.println(
"K-th smallest element in array : "
+ kthSmallest(arraycopy, 0 , length - 1 ,
kPosition));
}
}
}
|
Python3
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
def kthSmallest(arr, l, r, k):
if (k > 0 and k < = r - l + 1 ):
index = partition(arr, l, r)
if (index - l = = k - 1 ):
return arr[index]
if (index - l > k - 1 ):
return kthSmallest(arr, l, index - 1 , k)
return kthSmallest(arr, index + 1 , r,
k - index + l - 1 )
print ( "Index out of bound" )
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))
|
C#
using System;
class GFG
{
static int partitions( int []arr, int low, int high)
{
int pivot = arr[high], pivotloc = low, temp;
for ( int i = low; i <= high; i++)
{
if (arr[i] < pivot)
{
temp = arr[i];
arr[i] = arr[pivotloc];
arr[pivotloc] = temp;
pivotloc++;
}
}
temp = arr[high];
arr[high] = arr[pivotloc];
arr[pivotloc] = temp;
return pivotloc;
}
static int kthSmallest( int [] arr, int low,
int high, int k)
{
int partition = partitions(arr,low,high);
if (partition == k)
return arr[partition];
else if (partition < k )
return kthSmallest(arr, partition + 1, high, k );
else
return kthSmallest(arr, low, partition - 1, k );
}
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
{
Console.WriteLine( "K-th smallest element in array : " +
kthSmallest(arraycopy, 0, length - 1,
kPosition - 1));
}
}
}
|
Javascript
<script>
function _partition(arr, low, high)
{
let pivot = arr[high], pivotloc = low;
for (let i = low; i <= high; i++)
{
if (arr[i] < pivot)
{
let temp = arr[i];
arr[i] = arr[pivotloc];
arr[pivotloc] = temp;
pivotloc++;
}
}
let temp = arr[high];
arr[high] = arr[pivotloc];
arr[pivotloc] = temp;
return pivotloc;
}
function kthSmallest(arr, low, high, k)
{
let partition = _partition(arr, low, high);
if (partition == k - 1)
return arr[partition];
else if (partition < k - 1)
return kthSmallest(arr, partition + 1, high, k);
else
return kthSmallest(arr, low, partition - 1, k);
}
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
{
document.write(
"K-th smallest element in array : "
+ kthSmallest(arraycopy, 0, length - 1,
kPosition)+ "<br>" );
}
</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.
Related C++ function : std::nth_element in C++
Last Updated :
18 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...