高級排序算法之雙路快速排序
阿新 • • 發佈:2019-04-09
問題 規模 排序算法 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); }
經過性能測試,雙路排序算法對具有大量重復的數據排序性能很好,但是在此基礎上還可以進行優化,請查看三路快速排序算法的實現。
高級排序算法之雙路快速排序