思想:
分而治之,通过选定某一个元素作为基准值,将序列分为两部分,左边的序列小于基准值,右边的序列大于基准值, 然后再分别将左序列和右序列进行递归排序,直至每部分有序。
性质:这是不稳定的排序算法
复杂度分析
快速排序
时间复杂度:
最坏情况:O(N^2) 是单分支的树
最好情况:O(N * logN):是满二叉树/完全二叉树(大多数情况下复杂度是这个)
空间复杂度:
最好情况:O(logN) : 满二叉树/完全二叉树
最坏情况 O(N) : 单分支的树
视频实现过程
Hare法
思路:使用双指针从两端向中间移动,分别找到不符合顺序的元素并交换,直到指针相遇。
代码实现如下:
java
public class quickSort {
public static void main(String[] args) {
int[] arr = {34, 67, 334, 1, 45, 76, 87, 8};
quickSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
public static void quickSort(int[] array){
quick(array,0,array.length-1);
}
public static void quick(int[] array, int start,int end){
if(start > end){
return;
}
int div = parration(array,start,end);
quick(array,0,div-1);
quick(array,div+1, end);
}
public static int parration(int[] array, int left, int right){
int i = left;
int key = array[left];
while(left < right){
while(left < right && array[right] >= key){
right--;
}
while(left <right && array[left] <= key){
left++;
}
swap(array,left,right);
}
swap(array,i,left);
return left;
}
public static void swap(int[] array, int left, int right){
int temp = array[left];
array[left] =array[right];
array[right] = temp;
}
}
注意事项:
为什么array[right] >= key
这里必须要取等号,为什么:
这个等号必须要取,
因为如果不加这个等于符号
那么left和right如果同时都是一个数值的话
就不会进入循环了,则left和right就不会移动
left和right会一直进行交换
lefthe right 会一直交换这个相同的值(6)
但是left和right不会进行移动
如图所示:
为什么要先走right,而不是先走left
因为left不可以先走
不然会出问题:
以下是先走left的代码
如果left先走
那么left和right相遇的地方一定是比key大的
会导致在key的左边出现了比key大的值 ,违背了key的左边必须比key小的规则
而只有当right先移动的时候
right和left相遇的地方的值才会比key小
才符合排序结束之后,key左边的值都小于key,key右边的值都大于key这个规则
如图所示:
挖坑法
思路:使用一个基准值作为"坑",将小于基准值的元素填入左侧,大于基准值的元素填入右侧,最后将基准值归位。
java
public static int pparttion(int[] array, int left, int right){
int key = array[left];
while(left < right){
while(left < right && array[right] >= key){
right--;
}
while(left < right && array[left] <= key){
left++;
}
array[right] = array[left];
}
array[left] = key;
return left;
}
,