挑戰408——數據結構(8)——快速排序算法性能分析

先看看排序算法的C++代碼實現:

#include <iostream>
#include <vector>
using namespace std;
/*函數原型*/
void sort(std::vector<int> &vec);
void quickSort(std::vector<int> & vec, int start, int finish);
int partition(std::vector<int> & vec, int start, int finish);
/*主函數*/
int main(){
    vector<int> vec;
    for (int i = 0; i < 8; i++){
        int n;
        cin >> n;
        vec.push_back(n);
    }
    sort(vec);
    for(int k = 0; k < vec.size();k++){
        cout << vec[k] <<" ";
    }
    return 0;
}

/*
 *函數: quickSort
 *對下標位置之間的元素進行排序,包括開始位置和結束位置。 
 *Quicksort算法開始於“分割”後向量
 *使得小於指定的樞軸元素的所有元素都顯示在邊界的左側,
 *並且所有相等或更大的值都顯示在右側。
 *將子vector排序到邊界的左側和右側確保整個vector被排序。
 */ 
void quickSort(vector<int> & vec, int start, int finish) {
    if (start >= finish) return; //下標相同,返回
    int boundary = partition(vec, start, finish); //找樞紐
    quickSort(vec, start, boundary - 1); //對vec的樞紐左邊快速排序排序
    quickSort(vec, boundary + 1, finish);//對vec樞紐右邊快速排序
}
/*
 *該函數重新排列vector的元素,使得小元素被分組在向量的左端,
 *而大元素分組在右端。通過比較每個元素與最初從vec [start]
 *獲得的樞紐值來進行小和大的區別。當分區完成時,函數返回一
 *個邊界索下標,使得0對於所有i <boundary,vec [i] <pivot,
 *對於vec [i] == pivot,i == boundary,對於i > pivot,
 *vec [i]> = pivot, 
 */ 
int partition(vector<int> & vec, int start, int finish){
    int pivot = vec[start];
    int lh = start + 1;
    int rh = finish;
    while(true){
        while(lh < rh && vec[rh] >= pivot) rh--;
        while(lh < rh && vec[lh] < pivot) lh++;
        if(lh == rh) break;
        int temp;
        int tmp = vec[lh];
        vec[lh] = vec[rh];
        vec[rh] = tmp;
    }
    if (vec[lh] >= pivot) return start;
    vec[start] = vec[lh];
    vec[lh] = pivot;
    return lh;
}
/*
 *用wrapper函數將函數調用變得更加簡單*/
void sort(vector<int> &vec){
    quickSort(vec, 0, vec.size() - 1);
}

上述代碼在VS2015編譯成功:
在這裏插入圖片描述

性能分析

合併排序和Quicksort算法的實際運行時間的比較如下圖所示。Quicksort的這種實現往往比合並排序的執行速度快幾倍,這就是爲什麼程序員在實際中更頻繁地使用它的原因之一。此外,兩種算法的運行時間似乎都以大致相同的方式增長。
在這裏插入圖片描述
但是僅僅比較上圖,卻忽略了一點,只要Quicksort算法選擇一個接近於向量中值的樞軸,分區步驟就會將vector劃分成大致相等的部分。如果算法選擇其樞軸值較差,則兩個部分向量中的一個可能比另一個部分向量大得多,這違反了分治策略的原則。當要排序的vector中的數據是隨機的時,Quicksort往往表現很好,平均情況下爲O(N log N)。在最壞的情況下(比如這個vector已經排好了序 )性能退化爲O(N^2)。
不過,儘管在最壞的情況下這種它的表現很差,但是Quicksort在實踐中比大多數其他算法要快得多,目前它已經成爲一般分類過程的標準選擇。
我們可以使用幾種方式來增加樞紐實際上接近vector中值的可能性。一個簡單的方法是讓Quicksort實現隨機選擇pivot元素。雖然隨機過程仍然可能選擇不良的樞軸值,但是在遞歸分解的每個級別都不太可能會發生相同的錯誤。此外,原始vector的分佈總是隨機的,給定任何輸入,隨機選擇樞軸確保該向量的平均情況性能爲O(N log N)。另一種方法是從vector中選擇一些值,通常爲三或五個,並選擇這些值的中位數作爲樞紐。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章