1. 程式人生 > >高級排序算法之雙路快速排序

高級排序算法之雙路快速排序

問題 規模 排序算法 tle typename 方式 .cn i++ src

雙路快速排序算法分析

對於具有大量重復數據的排序按照之前的方式性能會很低,現在我們增加兩個標誌,想辦法把大量重復的數據分到兩部分,例如設置v作為標誌數據,讓等於v的數據分為兩部分,如下圖所示,這樣可以避免兩邊的數據出現一邊倒的情況。

技術分享圖片

根據以上算法的思想,代碼修改如下:

//雙路快速排序算法:解決具有大量重復源數據排序慢的問題
template<typename T>
int _partition2Ways(T arr[], int l, int r)
{
    //優化點2:通過隨機選擇元素標誌,防止對幾乎有序的數據排序慢的問題
    srand(time(NULL));
    swap(arr[l], arr[rand()%(r-l+1)+l]);
    
    T v = arr[l];

    int i = l+1, j = r;      //arr[l+1...j] < v ; arr[j+1...r] > v
    while(true)
    {
        while(i <= r && arr[i] < v)
            i++;
        while(j >= l && arr[j] > v)
            j--;

        if(i > j)
            break;

        swap(arr[i], arr[j]);
        i++;
        j--;
    }

    swap(arr[l], arr[j]);
    return j;
}

template<typename T>
void _quickSort2Ways(T arr[], int l, int r)
{
    //優化點1:小規模數據使用插入排序
    if(r-l <= 15)
    {
        insertionSort(arr, l, r);
        return;
    }

    int p = _partition2Ways(arr, l, r); //調用雙路快速排序
    _quickSort2Ways(arr, l, p-1);
    _quickSort2Ways(arr, p+1, r);
}

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

  

經過性能測試,雙路排序算法對具有大量重復的數據排序性能很好,但是在此基礎上還可以進行優化,請查看三路快速排序算法的實現。

高級排序算法之雙路快速排序