众所周知,Dual Pivot QuickSort 在串行版本中击败了合并排序。我认为 DPQ 的并行形式确实可能是有史以来最快的排序算法。原因是它的常数因子比 MergeSort 低,并且其最坏情况的时间复杂度发生的概率仅为 1/(n!)。如果 N 很大,则更喜欢 DPQ,如果可能的话,可能是多线程。但是并行性有一个支点或限制,由于线程管理,低于限制它的速度很慢。超出限制它会快得多。如果您有兴趣,下面是序列号(升序和降序)
protected static void ASC(int[]a, int left, int right, int div)
{
int len = 1 + right - left;
if (len < 27)
{
// insertion sort for small array
int P1 = left + 1;
int P2 = left;
while ( P1 <= right )
{
div = a[P1];
while(( P2 >= left )&&( a[P2] > div ))
{
a[P2 + 1] = a[P2];
P2--;
}
a[P2 + 1] = div;
P2 = P1;
P1++;
}
return;
}
int third = len / div;
// "medians"
int P1 = left + third;
int P2 = right - third;
if (P1 <= left)
{
P1 = left + 1;
}
if (P2 >= right)
{
P2 = right - 1;
}
int temp;
if (a[P1] < a[P2])
{
temp = a[P1]; a[P1] = a[left]; a[left] = temp;
temp = a[P2]; a[P2] = a[right]; a[right] = temp;
}
else
{
temp = a[P1]; a[P1] = a[right]; a[right] = temp;
temp = a[P2]; a[P2] = a[left]; a[left] = temp;
}
// 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)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
else if (a[k] > pivot2)
{
while (k < great && a[great] > pivot2)
{
great--;
}
temp = a[k]; a[k] = a[great]; a[great] = temp;
great--;
if (a[k] < pivot1)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
}
}
int dist = great - less;
if (dist < 13)
{
div++;
}
temp = a[less-1]; a[less-1] = a[left]; a[left] = temp;
temp = a[great+1]; a[great+1] = a[right]; a[right] = temp;
// subarrays
ASC(a, left, less - 2, div);
ASC(a, great + 2, right, div);
// equal elements
if (dist > len - 13 && pivot1 != pivot2)
{
for (int k = less; k <= great; k++)
{
if (a[k] == pivot1)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
else if (a[k] == pivot2)
{
temp = a[k]; a[k] = a[great]; a[great] = temp;
great--;
if (a[k] == pivot1)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
}
}
}
// subarray
if (pivot1 < pivot2)
{
ASC(a, less, great, div);
}
}
protected static void DSC(int[]a, int left, int right, int div)
{
int len = 1 + right - left;
if (len < 27)
{
// insertion sort for large array
int P1 = left + 1;
int P2 = left;
while ( P1 <= right )
{
div = a[P1];
while(( P2 >= left )&&( a[P2] < div ))
{
a[P2 + 1] = a[P2];
P2--;
}
a[P2 + 1] = div;
P2 = P1;
P1++;
}
return;
}
int third = len / div;
// "medians"
int P1 = left + third;
int P2 = right - third;
if (P1 >= left)
{
P1 = left + 1;
}
if (P2 <= right)
{
P2 = right - 1;
}
int temp;
if (a[P1] > a[P2])
{
temp = a[P1]; a[P1] = a[left]; a[left] = temp;
temp = a[P2]; a[P2] = a[right]; a[right] = temp;
}
else
{
temp = a[P1]; a[P1] = a[right]; a[right] = temp;
temp = a[P2]; a[P2] = a[left]; a[left] = temp;
}
// 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)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
else if (a[k] < pivot2)
{
while (k < great && a[great] < pivot2)
{
great--;
}
temp = a[k]; a[k] = a[great]; a[great] = temp;
great--;
if (a[k] > pivot1)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
}
}
int dist = great - less;
if (dist < 13)
{
div++;
}
temp = a[less-1]; a[less-1] = a[left]; a[left] = temp;
temp = a[great+1]; a[great+1] = a[right]; a[right] = temp;
// subarrays
DSC(a, left, less - 2, div);
DSC(a, great + 2, right, div);
// equal elements
if (dist > len - 13 && pivot1 != pivot2)
{
for (int k = less; k <= great; k++)
{
if (a[k] == pivot1)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
else if (a[k] == pivot2)
{
temp = a[k]; a[k] = a[great]; a[great] = temp;
great--;
if (a[k] == pivot1)
{
temp = a[k]; a[k] = a[less]; a[less] = temp;
less++;
}
}
}
}
// subarray
if (pivot1 > pivot2)
{
DSC(a, less, great, div);
}
}