📜  使用多线程快速排序

📅  最后修改于: 2021-04-21 23:56:36             🧑  作者: Mango

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

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

例子:

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

  1. 主线程调用quicksort方法。
  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)