Open In App

Median of an unsorted array using Quick Select Algorithm

Given an unsorted array arr[] of length N, the task is to find the median of this array. 
Median of a sorted array of size N is defined as the middle element when n is odd and average of middle two elements when n is even.

Examples: 



Input: arr[] = {12, 3, 5, 7, 4, 19, 26} 
Output:
Sorted sequence of given array arr[] = {3, 4, 5, 7, 12, 19, 26} 
Since the number of elements is odd, the median is 4th element in the sorted sequence of given array arr[], which is 7

Input: arr[] = {12, 3, 5, 7, 4, 26} 
Output:
Since number of elements are even, median is average of 3rd and 4th element in sorted sequence of given array arr[], which means (5 + 7)/2 = 6 



Naive Approach:  

Please refer to this article for the implementation of above approach.

Efficient Approach: using Randomized QuickSelect  

Below is the implementation of the above approach:  




// CPP program to find median of
// an array
 
#include "bits/stdc++.h"
using namespace std;
 
// Utility function to swapping of element
void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
 
// Returns the correct position of
// pivot element
int Partition(int arr[], int l, int r)
{
    int lst = arr[r], i = l, j = l;
    while (j < r) {
        if (arr[j] < lst) {
            swap(&arr[i], &arr[j]);
            i++;
        }
        j++;
    }
    swap(&arr[i], &arr[r]);
    return i;
}
 
// Picks a random pivot element between
// l and r and partitions arr[l..r]
// around the randomly picked element
// using partition()
int randomPartition(int arr[], int l,
                    int r)
{
    int n = r - l + 1;
    int pivot = rand() % n;
    swap(&arr[l + pivot], &arr[r]);
    return Partition(arr, l, r);
}
 
// Utility function to find median
void MedianUtil(int arr[], int l, int r,
                int k, int& a, int& b)
{
 
    // if l < r
    if (l <= r) {
 
        // Find the partition index
        int partitionIndex
            = randomPartition(arr, l, r);
 
        // If partition index = k, then
        // we found the median of odd
        // number element in arr[]
        if (partitionIndex == k) {
            b = arr[partitionIndex];
            if (a != -1)
                return;
        }
 
        // If index = k - 1, then we get
        // a & b as middle element of
        // arr[]
        else if (partitionIndex == k - 1) {
            a = arr[partitionIndex];
            if (b != -1)
                return;
        }
 
        // If partitionIndex >= k then
        // find the index in first half
        // of the arr[]
        if (partitionIndex >= k)
            return MedianUtil(arr, l,
                              partitionIndex - 1,
                              k, a, b);
 
        // If partitionIndex <= k then
        // find the index in second half
        // of the arr[]
        else
            return MedianUtil(arr,
                              partitionIndex + 1,
                              r, k, a, b);
    }
 
    return;
}
 
// Function to find Median
void findMedian(int arr[], int n)
{
    int ans, a = -1, b = -1;
 
    // If n is odd
    if (n % 2 == 1) {
        MedianUtil(arr, 0, n - 1,
                   n / 2, a, b);
        ans = b;
    }
 
    // If n is even
    else {
        MedianUtil(arr, 0, n - 1,
                   n / 2, a, b);
        ans = (a + b) / 2;
    }
 
    // Print the Median of arr[]
    cout << "Median = " << ans;
}
 
// Driver program to test above methods
int main()
{
    int arr[] = { 12, 3, 5, 7, 4, 19, 26 };
    int n = sizeof(arr) / sizeof(arr[0]);
    findMedian(arr, n);
    return 0;
}




// JAVA program to find median of
// an array
class GFG
{
    static int a, b;
 
    // Utility function to swapping of element
    static int[] swap(int[] arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        return arr;
    }
 
    // Returns the correct position of
    // pivot element
    static int Partition(int arr[], int l, int r)
    {
        int lst = arr[r], i = l, j = l;
        while (j < r)
        {
            if (arr[j] < lst)
            {
                arr = swap(arr, i, j);
                i++;
            }
            j++;
        }
        arr = swap(arr, i, r);
        return i;
    }
 
    // Picks a random pivot element between
    // l and r and partitions arr[l..r]
    // around the randomly picked element
    // using partition()
    static int randomPartition(int arr[], int l, int r)
    {
        int n = r - l + 1;
        int pivot = (int) (Math.random() % n);
        arr = swap(arr, l + pivot, r);
        return Partition(arr, l, r);
    }
 
    // Utility function to find median
    static int MedianUtil(int arr[], int l, int r, int k)
    {
 
        // if l < r
        if (l <= r)
        {
 
            // Find the partition index
            int partitionIndex = randomPartition(arr, l, r);
 
            // If partition index = k, then
            // we found the median of odd
            // number element in arr[]
            if (partitionIndex == k)
            {
                b = arr[partitionIndex];
                if (a != -1)
                    return Integer.MIN_VALUE;
            }
 
            // If index = k - 1, then we get
            // a & b as middle element of
            // arr[]
            else if (partitionIndex == k - 1)
            {
                a = arr[partitionIndex];
                if (b != -1)
                    return Integer.MIN_VALUE;
            }
 
            // If partitionIndex >= k then
            // find the index in first half
            // of the arr[]
            if (partitionIndex >= k)
                return MedianUtil(arr, l, partitionIndex - 1, k);
 
            // If partitionIndex <= k then
            // find the index in second half
            // of the arr[]
            else
                return MedianUtil(arr, partitionIndex + 1, r, k);
        }
 
        return Integer.MIN_VALUE;
    }
 
    // Function to find Median
    static void findMedian(int arr[], int n)
    {
        int ans;
        a = -1;
        b = -1;
 
        // If n is odd
        if (n % 2 == 1)
        {
            MedianUtil(arr, 0, n - 1, n / 2);
            ans = b;
        }
 
        // If n is even
        else
        {
            MedianUtil(arr, 0, n - 1, n / 2);
            ans = (a + b) / 2;
        }
 
        // Print the Median of arr[]
        System.out.print("Median = " + ans);
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 12, 3, 5, 7, 4, 19, 26 };
        int n = arr.length;
        findMedian(arr, n);
    }
}
 
// This code is contributed by 29AjayKumar




# Python3 program to find median of
# an array
import random
 
a, b = None, None;
 
# Returns the correct position of
# pivot element
def Partition(arr, l, r) :
 
    lst = arr[r]; i = l; j = l;
    while (j < r) :
        if (arr[j] < lst) :
            arr[i], arr[j] = arr[j],arr[i];
            i += 1;
         
        j += 1;
 
    arr[i], arr[r] = arr[r],arr[i];
    return i;
 
# Picks a random pivot element between
# l and r and partitions arr[l..r]
# around the randomly picked element
# using partition()
def randomPartition(arr, l, r) :
    n = r - l + 1;
    pivot = random.randrange(1, 100) % n;
    arr[l + pivot], arr[r] = arr[r], arr[l + pivot];
    return Partition(arr, l, r);
 
# Utility function to find median
def MedianUtil(arr, l, r,
                k, a1, b1) :
 
    global a, b;
     
    # if l < r
    if (l <= r) :
         
        # Find the partition index
        partitionIndex = randomPartition(arr, l, r);
         
        # If partition index = k, then
        # we found the median of odd
        # number element in arr[]
        if (partitionIndex == k) :
            b = arr[partitionIndex];
            if (a1 != -1) :
                return;
                 
        # If index = k - 1, then we get
        # a & b as middle element of
        # arr[]
        elif (partitionIndex == k - 1) :
            a = arr[partitionIndex];
            if (b1 != -1) :
                return;
                 
        # If partitionIndex >= k then
        # find the index in first half
        # of the arr[]
        if (partitionIndex >= k) :
            return MedianUtil(arr, l, partitionIndex - 1, k, a, b);
             
        # If partitionIndex <= k then
        # find the index in second half
        # of the arr[]
        else :
            return MedianUtil(arr, partitionIndex + 1, r, k, a, b);
             
    return;
 
# Function to find Median
def findMedian(arr, n) :
    global a;
    global b;
    a = -1;
    b = -1;
     
    # If n is odd
    if (n % 2 == 1) :
        MedianUtil(arr, 0, n - 1, n // 2, a, b);
        ans = b;
         
    # If n is even
    else :
        MedianUtil(arr, 0, n - 1, n // 2, a, b);
        ans = (a + b) // 2;
         
    # Print the Median of arr[]
    print("Median = " ,ans);
 
 
# Driver code
arr = [ 12, 3, 5, 7, 4, 19, 26 ];
n = len(arr);
findMedian(arr, n);
 
# This code is contributed by AnkitRai01




// C# program to find median of
// an array
using System;
 
class GFG
{
    static int a, b;
 
    // Utility function to swapping of element
    static int[] swap(int[] arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        return arr;
    }
 
    // Returns the correct position of
    // pivot element
    static int Partition(int []arr, int l, int r)
    {
        int lst = arr[r], i = l, j = l;
        while (j < r)
        {
            if (arr[j] < lst)
            {
                arr = swap(arr, i, j);
                i++;
            }
            j++;
        }
        arr = swap(arr, i, r);
        return i;
    }
 
    // Picks a random pivot element between
    // l and r and partitions arr[l..r]
    // around the randomly picked element
    // using partition()
    static int randomPartition(int []arr, int l, int r)
    {
        int n = r - l + 1;
        int pivot = (int) (new Random().Next() % n);
        arr = swap(arr, l + pivot, r);
        return Partition(arr, l, r);
    }
 
    // Utility function to find median
    static int MedianUtil(int []arr, int l, int r, int k)
    {
 
        // if l < r
        if (l <= r)
        {
 
            // Find the partition index
            int partitionIndex = randomPartition(arr, l, r);
 
            // If partition index = k, then
            // we found the median of odd
            // number element in []arr
            if (partitionIndex == k)
            {
                b = arr[partitionIndex];
                if (a != -1)
                    return int.MinValue;
            }
 
            // If index = k - 1, then we get
            // a & b as middle element of
            // []arr
            else if (partitionIndex == k - 1)
            {
                a = arr[partitionIndex];
                if (b != -1)
                    return int.MinValue;
            }
 
            // If partitionIndex >= k then
            // find the index in first half
            // of the []arr
            if (partitionIndex >= k)
                return MedianUtil(arr, l, partitionIndex - 1, k);
 
            // If partitionIndex <= k then
            // find the index in second half
            // of the []arr
            else
                return MedianUtil(arr, partitionIndex + 1, r, k);
        }
 
        return int.MinValue;
    }
 
    // Function to find Median
    static void findMedian(int []arr, int n)
    {
        int ans;
        a = -1;
        b = -1;
 
        // If n is odd
        if (n % 2 == 1)
        {
            MedianUtil(arr, 0, n - 1, n / 2);
            ans = b;
        }
 
        // If n is even
        else
        {
            MedianUtil(arr, 0, n - 1, n / 2);
            ans = (a + b) / 2;
        }
 
        // Print the Median of []arr
        Console.Write("Median = " + ans);
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int []arr = { 12, 3, 5, 7, 4, 19, 26 };
        int n = arr.Length;
        findMedian(arr, n);
    }
}
 
// This code is contributed by PrinciRaj1992




// JavaScript program to find median of
// an array
class GFG
{
     static a = 0;
     static b = 0;
    // Utility function to swapping of element
    static swap(arr, i, j)
    {
        var temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        return arr;
    }
    // Returns the correct position of
    // pivot element
    static Partition(arr, l, r)
    {
        var lst = arr[r];
        var i = l;
        var j = l;
        while (j < r)
        {
            if (arr[j] < lst)
            {
                arr = GFG.swap(arr, i, j);
                i++;
            }
            j++;
        }
        arr = GFG.swap(arr, i, r);
        return i;
    }
    // Picks a random pivot element between
    // l and r and partitions arr[l..r]
    // around the randomly picked element
    // using partition()
    static randomPartition(arr, l, r)
    {
        var n = r - l + 1;
        var pivot = parseInt((Math.random() % n));
        arr = GFG.swap(arr, l + pivot, r);
        return GFG.Partition(arr, l, r);
    }
    // Utility function to find median
    static MedianUtil(arr, l, r, k)
    {
        // if l < r
        if (l <= r)
        {
            // Find the partition index
            var partitionIndex = GFG.randomPartition(arr, l, r);
            // If partition index = k, then
            // we found the median of odd
            // number element in arr[]
            if (partitionIndex == k)
            {
                GFG.b = arr[partitionIndex];
                if (GFG.a != -1)
                {
                    return -Number.MAX_VALUE;
                }
            }
            else if (partitionIndex == k - 1)
            {
                GFG.a = arr[partitionIndex];
                if (GFG.b != -1)
                {
                    return -Number.MAX_VALUE;
                }
            }
            // If partitionIndex >= k then
            // find the index in first half
            // of the arr[]
            if (partitionIndex >= k)
            {
                return GFG.MedianUtil(arr, l, partitionIndex - 1, k);
            }
            else
            {
                return GFG.MedianUtil(arr, partitionIndex + 1, r, k);
            }
        }
        return -Number.MAX_VALUE;
    }
    // Function to find Median
    static findMedian(arr, n)
    {
        var ans = 0;
        GFG.a = -1;
        GFG.b = -1;
        // If n is odd
        if (n % 2 == 1)
        {
            GFG.MedianUtil(arr, 0, n - 1, parseInt(n / 2));
            ans = GFG.b;
        }
        else
        {
            GFG.MedianUtil(arr, 0, n - 1, parseInt(n / 2));
            ans = parseInt((GFG.a + GFG.b) / 2);
        }
        // Print the Median of arr[]
        console.log("Median = " + ans);
    }
    // Driver code
    static main(args)
    {
        var arr = [12, 3, 5, 7, 4, 19, 26];
        var n = arr.length;
        GFG.findMedian(arr, n);
    }
}
GFG.main([]);
 
// This code is contributed by aadityaburujwale.

Output
Median = 7

Time Complexity: 

  1. Best case analysis: O(1)
  2. Average case analysis: O(N)
  3. Worst case analysis: O(N2)

Auxiliary Space: O(N)


Article Tags :