什么是具有3向分区的QuickSort?
答案 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)
http://www.sorting-algorithms.com/static/QuicksortIsOptimal.pdf
另见:
http://www.sorting-algorithms.com/quick-sort-3-way
我认为面试问题版本也很有趣。它问,are there four partition versions of quicksort ......
答案 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路分区将排列原始数组并返回两个索引m1
和m2
,以便索引小于m1
的所有元素都将低于3
,所有索引大于或等于m1
且小于或等于m2
的元素将为等于3
,索引大于m2
的所有元素都将大于3
。
在这种特殊情况下,生成的数组可以是{ 1, 2, 3, 3, 9, 4, 15, 17, 25, 17 }
,值m1
和m2
可以是m1 = 2
和m2 = 3
。
请注意,生成的数组可能会根据用于分区的策略而更改,但数字m1
和m2
将相同。
答案 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();
}
}