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++
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
18 Sep, 2023
Like Article
Save Article