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 10Input: arr[] = {54, 64, 95, 82, 12, 32, 63}
Output: 12 32 54 63 64 82 95
Approach: The main idea of the approach is:
- The main thread calls the quicksort method.
- The method partitions the array and checks for the number of current threads.
- New threads is called for next step using the same parallel method.
- 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
// 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] + " " ); } } |
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 Java Foundation and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready.