一.先上代码
public class kuaiSu {
public static void main(String[] args) {
int[] arr={6,1,2,7,9,4,4,5,3,4,5,10,8};
merge(arr,0,arr.length-1);
for (int i = 0; i < arr.length; i++) {
int i1 = arr[i];
System.out.print( " "+i1);
}
}
public static void merge(int[] arr,int left, int right){
int le=left; //左侧指标
int ri=right; //右侧指标
if(le>ri) return; // 递归跳出
int temp =arr[left]; //基准点
while(le != ri){
while(arr[ri]>=temp && le < ri){
ri--;
}
arr[le] =arr[ri];
while(arr[le]<=temp && le < ri){
le++;
}
arr[ri] =arr[le];
}
arr[le]=temp;
merge(arr,left, le-1);
merge(arr,le+1, right);
}
}
二 基本介绍
快排与归并排序是互补的(https://blog.youkuaiyun.com/ff445566/article/details/90727201),归并是先拆在排序,逐渐在组合。
而快排是确定一个元素的准确位置,分组递归确定其他的元素的确定位置。
2.1快排的原理 :
先确定一个基数的准确位置,假如说,对一个无序数组排序,我先确定 5 的位置,让其左侧全部小于5,右侧全部大于五,
然后,对左右两侧在分别确定各字的基数,以此递归下去,逐步确定一个个的确定元素的准确位置。
利用左右指针,
只要右指针指向的数大于基数,我就一直行走下去,直到小于基数的时候,这时我让左指针=这个数,并且左指针开始移动;
左指针一直往右走,直到大于基数,然后我让右指针=这个数;并且让右指针移动。依次循环下去,一直到左右两个指针游标相等; 跳出循环;
这个时候让此时指针的指向=基数;
然后递归left,left-1; left+1,right;
2.2快排的优点:
实现简单,代码真的少(这也可能是传言面试手写快排概率高的原因了吧 哈哈哈),原地排序,不需要额外开辟新的辅助栈(这也是其速速较快的原因),移动数据次数少。
快排注意的几个小点 :
2.2.1注意跳出递归的地点在于(le>ri);
还有对于重复元素的处置,别忘了在指针游动的条件+ =;
2.2.2 对于小数组 插入排序比快排速度快;
时间复杂度平均O(N logn);