📜  使用多线程快速排序

📅  最后修改于: 2021-09-16 11:16:23             🧑  作者: Mango

QuickSort 是一种流行的基于分治算法的排序技术。在这种技术中,选择一个元素作为主元,并围绕它对数组进行分区。分区的目标是,给定一个数组和该数组的一个元素x作为主元,将x放在排序数组中的正确位置,并将所有较小的元素(小于x)放在x之前,并将所有较大的元素(大于比 x) 在 x 之后。

多线程允许同时执行程序的两个或多个部分,以最大限度地利用 CPU。这种程序的每一部分都称为一个线程。因此,线程是进程中的轻量级进程。

例子:

方法:方法的主要思想是:

  1. 主线程调用快速排序方法。
  2. 该方法对数组进行分区并检查当前线程的数量。
  3. 使用相同的并行方法为下一步调用新线程。
  4. 使用单一的普通快速排序方法。

下面是程序使用ForkJoinPool线程池来保持线程数与 CPU 数相同并重用线程:

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 {
  
    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

时间复杂度: O(N*log N)
辅助空间: O(N)