思想:
快速排序的核心思想是切分,即选定一个元素,大于他的放一边,小于等于他的放另一边。当切分好的数组恰好都是有序的时候,那整个数组就都有序了。为了保证切分的数组有序,就只用对两个子数组进行再次快排(切分),直至被切为单位长度1的数组。
切分操作至少保证了一个切分元素是在正确位置上的。
复杂度:
时间复杂度: O(nlgn) O ( n l g n )
空间复杂度: O(1) O ( 1 )
特点:
- 不占额外空间
- 平均性能好
- 非稳定排序
- 性能平均保持在 O(nlgn) O ( n l g n ) ,但是最坏情况为 O(n2) O ( n 2 ) (由于切分位置不确定),避免最坏情况的方法是将数组顺序随机化。
伪代码:
切分(原地切分较难,非原地切分较为简单):
partition(arr[], lo, hi){
div = arr[lo];
i = lo, j = hi+1;
while(i<j){
while(div>arr[++i])
if(i==hi) break;
while(div<=arr[--j])
if(j==lo) break;
if(i>=j) break;
exchange(arr[], i, j);
}
exchange(arr[], lo, j);
return j;
}
分治:
sort(arr[], lo, hi){
结束条件;
j = partition(arr[], lo, hi);
sort(arr[], lo, j-1);//j不用排序了
sort(arr[], j+1, hi);
}
优化
- 为防止切分导致性能下降,通过随机化初始顺序来提高性能。
- 对于重复较多的元素,采用三向切分方法可以提高性能。三向切分就是指,将和div相等的值单独归为一类,这样就可以提高效率。
- 小数组采用插排。