快速排序的实现&详解&笔试高频考察点&难点解析
1.快速排序
1.1快排介绍
其他的排序方法,像归并排序、堆排序等平均时间复杂度虽然与快排一样,都是O(n*logn),但是上述几种排序算法都是依赖于它们之间的比较,统称为比较排序。
1.2快速排序的基本步骤
快排的原理很直白,就是分治法。实现步骤也很容易理解。
-
以数组任意元素为基数(一般为队首)temp,将数组中比temp大的元素移动到数组右侧,比temp小的元素移动到数组左侧。
-
对基数相应的左右数组排序
左数组:arr[ low ]~arr[ index-1 ]
右数组:arr[ index+1]~arr[ high ]
-
重复1,2步,直到数组不再需要比较(为空或只有一个元素)。
所以不难发现,最重要的就是根据基数生成左右数组。
1.3根据基数分割数组
private static int getIndex(int[] arr, int l, int r) {
int temp=arr[l];
while (l<r){
while (l<r&&arr[r]>=temp)
r--;
arr[l]=arr[r];
while (l<r&&arr[l]<=temp)
l++;
arr[r]=arr[l];
}
arr[l]=temp;
return l;
}
步骤分析:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TtAIIgP4-1629365841544)(C:\Users\CoolGuy\AppData\Roaming\Typora\typora-user-images\image-20210819172701471.png)]
1.4代码展示
public class QSort {
public static void main(String[] args) {
int[] arr={300,54,647347,823,4,32,34,45,45};
// int[] arr = { 49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
QuickSort(arr,0,arr.length-1);
for (int x:arr)
System.out.println(x);
}
private static void QuickSort(int[] arr,int l,int r){
if(l<r){
System.out.println(l+" "+r);
int index=getIndex(arr,l,r);
QuickSort(arr,l,index-1);//性能提升??
QuickSort(arr,index+1,r);
}
}
private static int getIndex(int[] arr, int l, int r) {
int temp=arr[l];
while (l<r){
while (l<r&&arr[r]>=temp)
r--;
arr[l]=arr[r];
while (l<r&&arr[l]<=temp)
l++;
arr[r]=arr[l];
}
arr[l]=temp;
return l;
}
}
1.5容易出现的问题
- 注意分治的基线条件
if (l>=r)
return;
======
表示数组为[]或只有单个元素,此时不再不要排序
- 基数不再参与排序
QuickSort(arr,l,index-1);//性能提升??
QuickSort(arr,index+1,r);
=======
如果arr[index]再参于排序的话,会导致死循环
- 找出基数移动后的位置,要赋予对应的基数值
int temp=arr[l];
while (l<r){
while (l<r&&arr[r]>=temp)
r--;
arr[l]=arr[r];
while (l<r&&arr[l]<=temp)
l++;
arr[r]=arr[l];
}
arr[l]=temp;
return l;
========
根据代码不难观察出,此时的arr[index]的值是遍历过程中最后一个移动的元素的值,并不是基数。
arr[r]=arr[l];
}
arr[l]=temp;
return l;
根据代码不难观察出,此时的arr[index]的值是遍历过程中最后一个移动的元素的值,并不是基数。