Dual-Pivot Quicksort algorithm

New Dual-Pivot Quicksort algorithm
The new Quicksort algorithm uses partitioning a source array T [ ] a,
where T is primitive type (such as int, float, byte, char, double, long and short), to three
parts defined by two pivot elements P1 and P2 (and therefore, there are three pointers L,
K, G, and left and right — indices of the first and last elements respectively) shown in
Figure 1:


The algorithm provides the following steps:
1. For small arrays (length < 27), use the Insertion sort algorithm.
2. Choose two pivot elements P1 and P2. We can get, for example, the first element
a[left] as P1 and the last element a[right] as P2.
3. P1 must be less than P2, otherwise they are swapped. So, there are the following parts:
part I with indices from left+1 to L–1 with elements, which are less than P1,
part II with indices from L to K–1 with elements, which are greater or equal to P1
and less or equal to P2,
part III with indices from G+1 to right–1 with elements greater than P2,
part IV contains the rest of the elements to be examined with indices from K to G.
4. The next element a[K] from the part IV is compared with two pivots P1 and P2,
and placed to the corresponding part I, II, or III.
5. The pointers L, K, and G are changed in the corresponding directions.
6. The steps 4 - 5 are repeated while K G.
7. The pivot element P1 is swapped with the last element from part I,
the pivot element P2 is swapped with the first element from part III.
8. The steps 1 - 7 are repeated recursively for every part I, part II, and part III


Mathematical proof
It is proved that for the Dual-Pivot Quicksort the average number of comparisons is
2*n*ln(n), the average number of swaps is 0.8*n*ln(n), whereas classical Quicksort
algorithm has 2*n*ln(n) and 1*n*ln(n) respectively. Full mathematical investigation has
been done and will be copied here (TBD)


Implementation in Java™ programming language

public static void sort(int[] a) {
 sort(a, 0, a.length);
}
public static void sort(int[] a, int fromIndex, int toIndex) {
 rangeCheck(a.length, fromIndex, toIndex);
 dualPivotQuicksort(a, fromIndex, toIndex - 1, 3);
}
private static void rangeCheck(int length, int fromIndex, int toIndex) {
 if (fromIndex > toIndex) {
 throw new IllegalArgumentException("fromIndex > toIndex");
 }
 if (fromIndex < 0) {
 throw new ArrayIndexOutOfBoundsException(fromIndex);
 }
 if (toIndex > length) {
 throw new ArrayIndexOutOfBoundsException(toIndex);
 }
}
private static void swap(int[] a, int i, int j) {
 int temp = a[i];
 a[i] = a[j];
 a[j] = temp;
}
private static void dualPivotQuicksort(int[] a, int left,int right, int div) {
 int len = right - left;
 if (len < 27) { // insertion sort for tiny array
 for (int i = left + 1; i <= right; i++) {
for (int j = i; j > left && a[j] < a[j - 1]; j--) {
 swap(a, j, j - 1);
 }
 }
 return;
 }
 int third = len / div;
 // "medians"
 int m1 = left + third;
 int m2 = right - third;
 if (m1 <= left) {
 m1 = left + 1;
 }
 if (m2 >= right) {
 m2 = right - 1;
 }
 if (a[m1] < a[m2]) {
 swap(a, m1, left);
 swap(a, m2, right);
 }
 else {
 swap(a, m1, right);
 swap(a, m2, left);
 }
 // pivots
 int pivot1 = a[left];
 int pivot2 = a[right];
 // pointers
 int less = left + 1;
 int great = right - 1;
 // sorting
 for (int k = less; k <= great; k++) {
 if (a[k] < pivot1) {
 swap(a, k, less++);
 }
 else if (a[k] > pivot2) {
 while (k < great && a[great] > pivot2) {
 great--;
 }
 swap(a, k, great--);
 if (a[k] < pivot1) {
 swap(a, k, less++);
 }
 }
 }
 // swaps
 int dist = great - less;
 if (dist < 13) {
 div++;
 }
 swap(a, less - 1, left);
 swap(a, great + 1, right);
 // subarrays
 dualPivotQuicksort(a, left, less - 2, div);
 dualPivotQuicksort(a, great + 2, right, div);
// equal elements
 if (dist > len - 13 && pivot1 != pivot2) {
 for (int k = less; k <= great; k++) {
 if (a[k] == pivot1) {
 swap(a, k, less++);
 }
 else if (a[k] == pivot2) {
 swap(a, k, great--);
 if (a[k] == pivot1) {
 swap(a, k, less++);
 }
 }
 }
 }
 // subarray
 if (pivot1 < pivot2) {
 dualPivotQuicksort(a, less, great, div);
 }
}

参考: Dual-Pivot Quicksort algorithm
Vladimir Yaroslavskiy
iaroslavski@mail.ru






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值