標籤:
內容來自TsinghuaX: 30240184X 資料結構(2015秋)這門課的Vector一章,對bubblesort有兩次常數最佳化。
函數原型是這樣的:
void bubble(Rank lo, Rank hi);
void bubbleSort(Rank lo, Rank hi);
Rank即向量元素的秩,在此被定義為int型。lo和hi為待排序區間的左、右界樁。
外部通過調用 v.bubbleSort(lo, hi) 來給向量v的區間[lo,hi)排序,而bubbleSort調用bubble(lo,hi)實現對每個無序子區間的收縮。
最樸素的bubblesort大概是這樣,最好最壞平均情況都為O(n^2)
1 //最樸素版 2 void bubble(Rank lo, Rank hi) { 3 while (++lo < hi){//從左至右掃描,修正相鄰逆序對 4 if (_elem[lo - 1]>_elem[lo]){ 5 swap(_elem[lo - 1], _elem[lo]); 6 } 7 } 8 } 9 void bubbleSort(Rank lo, Rank hi){10 while (lo < hi) bubble(lo, hi--);//右界樁每次向左挪一位11 }
第一次改進後是這樣,這種改進很常見,能使最好情況變為為O(n)。
1 bool bubble(Rank lo, Rank hi) { 2 bool sorted=true;//增設sorted變數,記錄此次掃描是否發生交換(未發生交換則sorted=true) 3 while (++lo < hi){ 4 if (_elem[lo - 1]>_elem[lo]){ 5 sorted = false; 6 swap(_elem[lo - 1], _elem[lo]); 7 } 8 } 9 return sorted;//返回是否已有序10 }11 void bubbleSort(Rank lo, Rank hi){12 while (!bubble(lo, hi--));//一趟掃描沒有發生交換(檢測結果為sorted)則排序完成13 }
第二次改進後是這樣,可以跳躍式地收縮區間,降低了平均情況常數因子
1 Rank bubble(Rank lo, Rank hi) { 2 Rank last=lo;//設定last變數,記錄最後一次交換的位置 3 while (++lo < hi){;} 4 5 swap(_elem[lo - 1], _elem[lo]); 6 if (_elem[lo - 1]>_elem[lo]){ 7 last = lo 8 } 9 return last;//last及以後的元素都已就位,不必再進行掃描10 }11 void bubbleSort(Rank lo, Rank hi){12 while (lo<(hi=bubble(lo, hi--)));//將右界樁挪到最後一次last位置13 }
第二次改進可用來描述
bubblesort的常數最佳化