快速排序的优化过程可以参考我的另一篇博文:《快速排序及其优化过程总结》
快排示意图:
/**
* 快速排序
*/
public class test2_8 {
static Comparable a[] = {"49","38","65","97","76","13","27"};
private static void qSort(int left,int right){
if(left<right){
//定位并使定位好的元素左边都比其小,右边都比其大
int mid = partition(left,right);
//递归
qSort(left,mid-1);
qSort(mid+1,right);
}
}
private static int partition(int left,int right){
int i=left,j=right+1;
Comparable x = a[left],temp;
while(true){
//寻找第一个比x元素大的元素的下标
while(a[++i].compareTo(x)<0&&i<right);
//寻找第一个比x元素小的元素的下标
while(a[--j].compareTo(x)>0);
if(i>=j){
a[left] = a[j];
a[j] = x;
break;
}
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return j;
}
public static void main(String[] args) {
System.out.print("排序前:");
for(int i=0;i<a.length;i++)
System.out.print(a[i]+" ");
System.out.println();
qSort(0,a.length-1);
System.out.print("排序后:");
for(int i=0;i<a.length;i++)
System.out.print(a[i]+" ");
}
}
运行结果如下:
排序前:49 38 65 97 76 13 27
排序后:13 27 38 49 65 76 97
总结:
①细心的读者会发现第20行代码和第22行代码
while(a[++i].compareTo(x)<0&&i<right);
while(a[--j].compareTo(x)>0);
两行代码的区别是i<right条件,为什么第一行多了这个条件而第二行代码却没有这个条件呢?
原因如下:a[left](即数组的首元素)后面的元素都有可能比其本身小,没有约束的遍历下去可能会导致数组下标越界,因为++i表明其最多只能遍历n-1个元素(一开始i=left),无法遍历到数组首元素。而不对--j加条件的原因是一开始j=right+1,所以第一遍--j后j就能率先遍历到最后一个元素,然后依次向前,最多可遍历n个数组元素
②break;语句前第24行代码是a[left] = a[j];而不是a[left] = a[i];为什么呢?
因为如果i≠j,则i下标对应的数组元素一定比x元素大,而j下标对应的数组元素一定比x元素小,快排中(升序情况下)选中元素x左边的元素都比其小,右边的必须比其大,所以应该把比x元素小的元素和x元素交换位置,使其位于x元素左边。

本文详细介绍了快速排序算法的实现过程,并通过一个具体的示例展示了排序前后数组的变化情况。此外,还深入分析了快排核心代码的设计思路及背后的逻辑。
1332

被折叠的 条评论
为什么被折叠?



