快速排序的兩種C++實現,複雜度分析及優化

快速排序可能是面試中最常被考察的算法了,求職者一定要非常熟練地掌握掌握這一算法。
下面介紹該算法的兩種C++實現方法:

  • 方法一:
void quickSort(vector<int> &nums, int b, int e) {
    if (b < e) {
        int pivot = nums[b];   //選取第一個元素爲pivot
        int i = b, j = e;
        while (i < j) {
            while (i < j && nums[j] > pivot) {
                j--;
            }
            if (i < j) {
                nums[i++] = nums[j];
            }
            while (i < j && nums[i] < pivot) {
                i++;
            }
            if (i < j) {
                nums[j--] = nums[i];
            }
        }
        nums[i] = pivot;
        quickSort(nums, b, i - 1);
        quickSort(nums, i + 1, e);
    }
}

這種方法將partition子程序與主程序寫在一起,看起來更加簡潔。

  • 方法二
int partition(vector<int> &nums, int left, int right) {
    int pivot = nums[left], l = left + 1, r = right;  //選取第一個元素爲pivot
    while (l <= r) {
        if (nums[l] > pivot && pivot > nums[r])
            swap(nums[l++], nums[r--]);
        if (nums[r] >= pivot)
            r--;
        if (nums[l] <= pivot)
            l++;
    }
    swap(nums[r], nums[left]);
    return r;
}

void quickSort2(vector<int> &nums, int b, int e) {
    if (b < e) {
        int index = partition(nums, b, e);
        quickSort2(nums, b, index - 1);
        quickSort2(nums, index + 1, e);
    }
}

通常情況下,我們把partition子程序獨立出來,這樣思路更清晰。另外partition子程序在處理“第N大的數”這類問題的時候也很有幫助。

複雜性分析
當劃分比較平衡,即左右兩邊的元素個數都接近n/2的時候,通過主定理不難得出快速排序的算法複雜度爲O(nlogn)。
但如果數組本身基本有序時,如果還是選擇第一個或者最後一個元素作爲pivot,那麼每次劃分後左右兩邊就會極不平衡,時間複雜度就會退化爲O(n^2)。可考慮採用以下方法進行優化:

  • 隨機選擇一個元素作爲pivot,可利用語言自帶的rand函數實現;
  • 選擇第一個、最後一個、最中間一個三者中的中值作爲pivot。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章