1. 什么是快速排序:最突出的特点就是通过数字之间的比较找到基准数的位置,然后根据该位置进行递归分治
2. 画图分析,示例数组为{4, 7, 6, 5, 3, 2, 8, 1}
1)数组{4, 7, 6, 5, 3, 2, 8, 1}以4为基准,分治数组
2) 紧接着递归进入数组中小于 4 的这部分
以 3 为基准发现都在3的左边,右边再次递归时,startIdx = 2 + 1 endIdx = 2,2是3这个数字在该数组中的索引位置,startIdx > endIdx 所以右边的递归就退出了
3)紧接着递归进入数组中小于 3的部分
以 2为基准发现就只有1,在2的左边。右边再次递归时, startIdx = 1 + 1 endIdx = 1,1是2这个数字在该数组中的索引位置,startIdx > endIdx 所以右边的递归就退出了;
左边再次递归时,startIndex = 0 endIndex = 1 - 1,0是1这个数字在该数组中的索引位置,startIdx == endIdx 所以右边的递归就退出了;
4)此时整体基准4左边部分排序完成
5)回到基准4的右边部分
以 5 为基准发现都在5的右边边,左边再次递归时,startIdx = 4 endIdx = 4 - 1,4是5这个数字在该数组中的索引位置,startIndex > endIndex 所以左边的递归就退出了;
6)紧接着递归进入基准5右边的部分
以 6 为基准发现都在6的右边,左边再次递归时,startIdx = 5 endIdx = 5 - 1,5是6这个数字在该数组中的索引位置,startIdx > endIdx 所以左边的递归就退出了;
7)紧接着递归进入基准6右边的部分
7所在的位置为基准位置,左边再次进入递归时, startIndex = 6 endIndex = 6 - 1,6是7这个数字在该数组中的索引位置,startIdx > endIdx 所以左边的递归就退出了;
右边再次进入递归时, startIdx = 6 + 1 endIdx = 7,7是8这个数字在该数组中的索引位置,startIdx == endIdx 所以右边的递归就退出了;
8)至此所有的递归都已回退,数组也就排序好了
3. 时间复杂度:O(nlogn)
4. show me the code
public class Test {
public static void main(String[] args) {
int[] arr = {4, 7, 6, 5, 3, 2, 8, 1};
quickSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
private static int getPartition(int[] arr, int startIdx, int endIdx) {
int p = arr[startIdx];
int left = startIdx;
int right = endIdx;
while (left < right) {
while (left < right && arr[right] > p) {
right--;
}
while (left < right && arr[left] <= p) {
left++;
}
if (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
int temp = arr[left];
arr[left] = p;
arr[startIdx] = temp;
return left;
}
public static void quickSort(int[] arr, int startIdx, int endIdx) {
if (startIdx >= endIdx) {
return;
}
int partition = getPartition(arr, startIdx, endIdx);
quickSort(arr, startIdx, partition - 1);
quickSort(arr, partition + 1, endIdx);
}
}
5. 附上漫画算法快排讲解的地址:https://mp.weixin.qq.com/s/PQLC7qFjb74kt6PdExP8mw
6. 画图部分写的很啰嗦,目的是为了自己复习的时候可以看懂,如有不对的地方请多指正~