快速排序应该是面试或者笔试的常客了,经常遇到,但是手写一个快速排序还是有点生疏,于是就做个总结。
快速排序简单原理
快速排序,因为大大的减少了比较次数和移动次数,所以在效率上有很大提升,尤其在大数据量的时候,它的性能越趋于稳定,但是它也有缺点,那就是依赖待排序数组,如果是大规模的随机无序数组,那么快速排序效率就很厉害;但是当待排数组有序的时候,快速排序就会很慢。总体来说快速排序的平均时间复杂度是O(nlogn)。
快速排序是一种分治的排序算法,它和归并排序有些类似,都是将一个数组分为两个子数组,将两部分独立排序。但是它们是互补的:归并排序是将数组分为两个子数组,并将有序的子数组归并以将整个数组排序;而快速排序则是当两个数组都有序的时候,整个数组也就有序了。归并排序的递归是发生在处理数组之前,且它的切分不受数组元素影响,都是对半分;而快速排序则是递归发生在处理数组之后,而且数组的切分依赖于数组的元素,这也是它不稳定的原因所在。
排序大体流程:
- 选取一个标兵,一般选择最左边,即第一个元素。
- 定义两个游标,一个从数组最左端开始向右移动,一个从数组最右端开始向左移动。
- 左游标开始移动,遇到比标兵大的数的时候停下;这个时候右游标开始移动,直到找到一个比标兵小的数停下,交换两个游标的数。继续移动直到两个游标相遇为止。
- 当两个游标相遇的时候,将左游标的值与标兵互换,这个时候标兵的值就处在了正确的位置(左边比它小,右边比它大)。一轮递归结束。
- 递归上述步骤,直到切分的数组只有一个元素的时候,即所有元素都在正确的位置了,结束。
代码实现java版本
package com.lzl.test.http;
/**
* Created by lzl on 2018/3/26.
*/
public class Test8 {
public static void main(String args[]){
int[] a={6,3,5,1,0,9,4,2,11,33,22};
FastSort(a,0,a.length-1);
for(int i=0;i<a.length;i++){
System.out.print(a[i]+",");
}
}
public static void FastSort(int[] a,int left,int right){
int k =left;
int i = left+1;
int j = right;
while(i<=j){
if(a[i]>a[k]){
if(a[k]>a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
j--;
}else{
j--;
continue;
}
}
i++;
}
i=i-1;
int temp = a[i];
a[i]=a[k];
a[k]=temp;
if(left<(i-1)) {
FastSort(a, left, i - 1);
}
if((i + 1)<right) {
FastSort(a, i + 1, right);
}
}
}