Quick Sort using Multi-threading

QuickSort is a popular sorting technique based on divide and conquer algorithm. In this technique, an element is chosen as a pivot and the array is partitioned around it. The target of partition is, given an array and an element x of the array as a pivot, put x at its correct position in a sorted array and put all smaller elements (smaller than x) before x, and put all greater elements (greater than x) after x.

Multi-threading allows concurrent execution of two or more parts of a program for maximum utilization of CPU. Each part of such program is called a thread. So, threads are light-weight processes within a process.

Examples:

Input: arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
Output: 1 2 3 4 5 6 7 8 9 10

Input: arr[] = {54, 64, 95, 82, 12, 32, 63}
Output: 12 32 54 63 64 82 95



Approach: The main idea of the approach is:

  1. The main thread calls the quicksort method.
  2. The method partitions the array and checks for the number of current threads.
  3. New threads is called for next step using the same parallel method.
  4. Use the single normal quicksort method.

Below is the program uses ForkJoinPool thread pool to keep number of thread same as the number of CPUs and reuse the threads:

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.io.*;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
  
public class QuickSortMutliThreading
    extends RecursiveTask<Integer> {
  
    int start, end;
    int[] arr;
  
    /**
     * Finding random pivoted and partition
     * array on a pivot.
     * There are many different
     * partitioning algorithms.
     * @param start
     * @param end
     * @param arr
     * @return
     */
    private int partion(int start, int end,
                        int[] arr)
    {
  
        int i = start, j = end;
  
        // Decide random pivot
        int pivote = new Random()
                         .nextInt(j - i)
                     + i;
  
        // Swap the pivote with end
        // element of array;
        int t = arr[j];
        arr[j] = arr[pivote];
        arr[pivote] = t;
        j--;
  
        // Start partioning
        while (i <= j) {
  
            if (arr[i] <= arr[end]) {
                i++;
                continue;
            }
  
            if (arr[j] >= arr[end]) {
                j--;
                continue;
            }
  
            t = arr[j];
            arr[j] = arr[i];
            arr[i] = t;
            j--;
            i++;
        }
  
        // Swap pivote to its
        // correct position
        t = arr[j + 1];
        arr[j + 1] = arr[end];
        arr[end] = t;
        return j + 1;
    }
  
    // Function to implement
    // QuickSort method
    public QuickSortMutliThreading(int start,
                                   int end,
                                   int[] arr)
    {
        this.arr = arr;
        this.start = start;
        this.end = end;
    }
  
    @Override
    protected Integer compute()
    {
        // Base case
        if (start >= end)
            return null;
  
        // Find partion
        int p = partion(start, end, arr);
  
        // Divide array
        QuickSortMutliThreading left
            = new QuickSortMutliThreading(start,
                                          p - 1,
                                          arr);
  
        QuickSortMutliThreading right
            = new QuickSortMutliThreading(p + 1,
                                          end,
                                          arr);
  
        // Left subproblem as separate thread
        left.fork();
        right.compute();
  
        // Wait untill left thread complete
        left.join();
  
        // We don't want anything as return
        return null;
    }
  
    // Driver Code
    public static void main(String args[])
    {
        int n = 7;
        int[] arr = { 54, 64, 95, 82, 12, 32, 63 };
  
        // Forkjoin ThreadPool to keep
        // thread creation as per resources
        ForkJoinPool pool
            = ForkJoinPool.commonPool();
  
        // Start the first thread in fork
        // join pool for range 0, n-1
        pool.invoke(
            new QuickSortMutliThreading(
                0, n - 1, arr));
  
        // Print shorted elements
        for (int i = 0; i < n; i++)
            System.out.print(arr[i] + " ");
    }
}

chevron_right


Output:

12 32 54 63 64 82 95

Time Complexity: O(N*log N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.