高级排序算法之三路快速排序

三路快速排序算法分析

双路快速排序算法把等于v的数据分为两部分,方式了数据量一边倒的情况,三路排序算法把排序的数据分为三部分,分别为小于v,等于v,大于v,这样三部分的数据中,等于v的数据在下次递归中不再需要排序,小于v和大于v的数据也不会出现某一个特别多的情况(如下图所示),通过此方式三路快速排序算法的性能更优。

 三路快速排序主要关注三个标志,分别为lt,i,gt,这三个标志会把数据分为四部分,arr[l+1...lt]的数据全部小于v,arr[lt+1...i-1]的数据等于v,arr[i...gt-1]的为待排序的数据,arr[gt...r]的数据大于v,具体的代码实现如下:

template<typename T>
void _quickSort3Ways(T arr[], int l, int r)
{
    //小规模数据使用插入排序
    if(r-l <= 15)
    {
        insertionSort(arr, l, r);
        return;
    }

    // 随机在arr[l...r]的范围中, 选择一个数值作为标定点pivot
    swap( arr[l], arr[rand()%(r-l+1)+l ] );
    T v = arr[l];

    int lt = l; //arr[l+1...lt] < v
    int gt = r+1; //arr[gt...r] > v
    int i = l+1;  //arr[lt+1...gt-1] == v
    while(i < gt)
    {
        if(arr[i] < v)
        {
            swap(arr[i], arr[lt+1]);
            i++;
            lt++;
        }
        else if(arr[i] > v)
        {
            swap(arr[i], arr[gt-1]);
            gt--;
        }
        else    //arr[i] == v
            i++;            
    }
    swap(arr[l], arr[lt]);
    
    _quickSort3Ways(arr, l, lt-1);
    _quickSort3Ways(arr, gt, r);
}

template<typename T>
void quickSort3Ways(T arr[], int n)
{
    srand(time(NULL));
    _quickSort3Ways(arr, 0, n-1);
}

三路快速排序算法对具有大量重复的数据排序性能很好。

排序算法性能对比

下边对比相同数据量下,几乎有序的数据、大量重复的数据情况下,归并排序、希尔排序、不同快速排序、双路快速排序、三路快速排序的性能:

通过初步对比百万数据量的排序得出以下几点结论:

1、随机的百万数据量排序中,快速排序算法性能相对较好。

2、对于百万几乎有序的数据量(不存在重复数据) ,希尔排序和归并排序性能最好,快速排序性能也不差。

3、对于百万具有大量重复数据的情况,之前未优化过的普通快速排序性能很差,三路快速排序算法性能最好。

以上是粗略测试,不同的数据可能具体结果会有差异,但是如果通过大量数据进行多轮测试,快速排序算法性能会最优,毕竟快速排序算法的时间复杂度为O(nlog(n))。

 

posted @ 2019-04-08 23:51  心梦无痕bhl  阅读(1054)  评论(0编辑  收藏  举报