快排優化
2.聚集元素
3.尾遞迴優化
4.插入排序處理小陣列
快排演算法是基於分治策略的排序演算法,其基本思想是,對於輸入的陣列a[low, high],按以下兩個步驟進行排序:
1)劃分:以a[p]為基準將a[low: high]劃分為三段a[low:p-1],a[p]和a[p+1:high],使得a[low:p-1]中任何乙個元素小於等於a[p], 而a[p+1: high]中任何乙個元素大於等於a[p]。
2)遞迴求解:通過遞迴呼叫快速排序演算法分別對a[low:p-1]和a[p+1:high]進行排序。
【tip】關於p的選取,有固定選取、隨機選取、三數取中法。
//閉區間[l,r],hoare雙向掃瞄
intpartition
(vector<
int>
& arr,
int l,
int r)
}void
quicksort
(vector<
int>
& arr,
int l,
int r)
}
使用vector,需要傳引用,使用陣列則不需要。
採用雙向掃瞄,單向掃瞄對於重複元素會退化成為o(n^2)。
雙向掃瞄採用嚴格大於、嚴格小於,否則對於重複元素也會退化成o(n^2)。
簡潔版:
void
quick_sort
(vector<
int>
& arr,
int l,
int r)
quick_sort
(arr, l, j)
;quick_sort
(arr, j +
1, r)
;// 遞迴
}
最樸素的方法就是固定選取最左元素或者最右元素,沒什麼好說的。
如上,使用隨機函式,演算法平均複雜度為o(nlgn),證明。
int pivot=arr[l+
rand()
%(r-l+1)
];
雖然隨機劃分平均效能已經很好了,但總有使得劃分情況最差的隨機性。一種更有效的選取方法為三數取中。
【思想】選取陣列開頭,中間和結尾的元素,通過比較,選擇中間的值作為快排的劃分點。
顯然使用三數中值分割法消除了預排序輸入的不好情形,並且減少快排大約14%的比較次數。
int
selectmedianofthree
(int a,
int b,
int c)
intpartition
(vector<
int>
& arr,
int l,
int r)
【思想】在一次劃分結束後,將與本次劃分點相等的元素聚集在一起,再分割時,不再對聚集過的元素進行分割。partition函式返回兩個下標,乙個為相等的聚集元素左邊界,乙個是右邊界。
詳細分析
vector<
int>
partition2
(vector<
int>
& arr,
int l,
int r)
return;}
void
quicksort
(vector<
int>
& arr,
int l,
int r)
詳細分析
【分析】快排遞迴函式兩次呼叫自身時處於遞迴函式尾部,可以將其中任意乙個放到末尾,優化為迭代,有效減少遞迴棧深度。選擇區間更長的乙個,置於末尾優化為迭代。
void
quicksort
(vector<
int>
& arr,
int l,
int r)
else
}}
【目的】減少棧深度,有效防止爆棧。
資料量小時,插入排序效率比較高,因為其常係數比較小。
當快排達到一定深度後,劃分的區間很小時,再使用快排的效率不高。當待排序列的長度達到一定數值後,可以使用插入排序。由《資料結構與演算法分析》(mark allen weiness所著)可知,當待排序列長度為5~20之間,此時使用插入排序能避免一些有害的退化情形。
void
quicksort
(vector<
int>
& arr,
int low,
int high)
int pivotpos =
partition
(arr,low,high)
;quicksort
(arr,low,pivotpos)
;quicksort
(arr,pivotpos+
1,high);}
void
insertsort
(vector<
int>
& arr,
int m,
int n)
arr[j +1]
= temp;
}}
參考文章:
五種排序演算法 快速排序
1 在陣列中選乙個基準數 通常為陣列第乙個 2 將所有比基準值小的值擺放在基準的前面,所有比基準值大的擺放在基準的後面 相同的數可以放到任意一邊 在這個分割槽推出之後,該基準就處於數列的中間位置。3 遞迴地把 基準值前面的子數列 和 基準值後面的子數列 進行排序。下面以數列a 30,40,10,20...
快速排序及五種優化(模板)
快速排序排序使用分治的思想,通過一趟排序將待排序列分割成兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小。之後分別對這兩部分記錄繼續進行排序,遞迴地以達到整個序列有序的目 1 選擇基準 在待排序列中,按照某種方式挑出乙個元素,作為 基準 2 分割操作 以該基準在序列中的實際位置,把序列分成兩...
C 演算法 五 快速排序
using system namespace quicksorter public void sort int list,int low,int high mid low high 1 pivot list mid swap ref list low ref list mid l low 1 r h...