Quicksort有3路分区

时间:2009-06-02 19:27:45

标签: algorithm quicksort

什么是具有3向分区的QuickSort?

7 个答案:

答案 0 :(得分:50)

想象一下阵列:

3, 5, 2, 7, 6, 4, 2, 8, 8, 9, 0

两个分区快速排序会选择一个值,比如说4,并且在数组的一侧放置大于4的每个元素,而在另一侧放置少于4的每个元素。像这样:

3, 2, 0, 2, 4, | 8, 7, 8, 9, 6, 5

三个分区快速排序将选择两个值进行分区并以此方式拆分数组。让我们选择4和7:

3, 2, 0, 2, | 4, 6, 5, 7, | 8, 8, 9

这只是常规快速排序的一个小变化。

继续对每个分区进行分区,直到对数组进行排序。 运行时在技术上是nlog 3 (n),它与常规快速排序的nlog 2 (n)略有不同。

答案 1 :(得分:16)

答案 2 :(得分:12)

如果您真的使用Akra-Bazzi formula将数学分区作为参数,然后优化该参数,您将发现e(= 2.718 ...)分区提供最快的性能。然而,在实践中,我们的语言结构,cpus等都针对二进制操作进行了优化,因此标准分区为两组将是最快的。

答案 3 :(得分:12)

我认为3路分区是由Djstrka完成的。

考虑一个包含元素{ 3, 9, 4, 1, 2, 3, 15, 17, 25, 17 }的数组。

基本上你设置了3个分区:小于,等于和大于某个分支。等于分区不需要进一步排序,因为它的所有元素已经相等。


例如,如果我们选择第一个3作为枢轴,那么使用Dijkstra的3路分区将排列原始数组并返回两个索引m1m2,以便索引小于m1的所有元素都将低于3,所有索引大于或等于m1且小于或等于m2的元素将为等于3,索引大于m2的所有元素都将大于3

在这种特殊情况下,生成的数组可以是{ 1, 2, 3, 3, 9, 4, 15, 17, 25, 17 },值m1m2可以是m1 = 2m2 = 3

请注意,生成的数组可能会根据用于分区的策略而更改,但数字m1m2将相同。

答案 4 :(得分:1)

我认为它与Dijkstra分区方式有关,其中分区的元素小于,等于和大于枢轴。只有较小和较大的分区必须递归排序。您可以在the walnut看到交互式可视化并使用它进行播放。我在那里使用的颜色是红色/白色/蓝色,因为分区方法通常称为"荷兰国旗问题"

答案 5 :(得分:0)

3种方式的快速排序基本上将数组分为3部分。第一部分小于枢轴,第二部分等于枢轴,第三部分大于枢轴,这是线性时间分割算法。 此分区类似于荷兰国旗问题。

答案 6 :(得分:-2)

  //code to implement Dijkstra 3-way partitioning

  package Sorting;

  public class QuickSortUsing3WayPartitioning {

private int[]original;
private int length;
private int lt;
private int gt;

public QuickSortUsing3WayPartitioning(int len){
    length = len;
    //original = new int[length];

    original = {0,7,8,1,8,9,3,8,8,8,0,7,8,1,8,9,3,8,8,8};

}

public void swap(int a, int b){ //here indexes are passed
    int temp = original[a];
    original[a] = original[b];
    original[b] = temp;
}

public int random(int start,int end){
    return (start + (int)(Math.random()*(end-start+1)));
}

public void partition(int pivot, int start, int end){
    swap(pivot,start);  // swapping pivot and starting element in that subarray

    int pivot_value = original[start];
    lt = start;
    gt = end;

    int i = start;
    while(i <= gt) {

        if(original[i] < pivot_value) {
            swap(lt, i);
            lt++;
            i++;
        }

        if(original[i] > pivot_value) {
            swap(gt, i);
            gt--;
        }
        if(original[i] == pivot_value)
            i++;
    }
}

public void Sort(int start, int end){
    if(start < end) {

        int pivot = random(start,end); // choose the index for pivot randomly
        partition(pivot, start, end); // about index the array is partitioned

        Sort(start, lt-1);
        Sort(gt+1, end);

    }
}

public void Sort(){
    Sort(0,length-1);
}

public void disp(){
    for(int i=0; i<length;++i){
        System.out.print(original[i]+" ");
    }
    System.out.println();
}

public static void main(String[] args) {

    QuickSortUsing3WayPartitioning qs = new QuickSortUsing3WayPartitioning(20);
    qs.disp();

    qs.Sort();
    qs.disp();

}

}