分析
快速排序其实跟归并排序有些类似,都需要进行不停的的分组,采取递归的方式进行不停的分。只是其在分的时候,就已经算是在排序了,等合并的时候其实子数组都是已经有序的了
在划分的时候,一般选用原数组中的第一个数据作为分界值,进行划分,在后面的数据与分界值进行比较的时候,小于等于分界值的数,就放在分界值的右边,大于分界值的数放在左边,在不停的分界,知道不能再进行分的时候,就开始将数据进行合并。不过这里需要注意的是,分界值确定以后,右边的数肯定是小于等于分界值的,而左边的数是大于分界值的,相当于我们在排序分界值两边数据的时候,只要两边的数据有序了,合并起来分界值以后肯定也是有序的,所以在分组以后,分界值可以就不包含进去了。
代码
/*
对数组a中从lo到hi之间的元素进行排序
*/
private static void sort(Integer[] a,int lo,int hi){
if (lo>=hi){
return;
}
int partition = partition(a, lo, hi);
sort(a,lo,partition-1);
sort(a,partition+1,hi);
}
/*
对数组a中,从索引lo到索引hi之间的元素进行分组,并返回分组界限对应的索引
*/
private static int partition(Integer[] a, int lo, int hi) {
int key=a[lo];
int left=lo;
int right=hi;
while (true){
while (a[right]>key){
--right;
if (right==lo){
break;
}
}
while (a[left]<=key){
++left;
if (left==hi){
break;
}
}
if (left>=right){
break;
}else {
int i = a[left];
a[left] = a[right];
a[right] = i;
}
}
int i = a[right];
a[right] = a[lo];
a[lo] = i;
return right;
}
💫疑问点
自己在开始看视频练习的时候,会很奇怪为什么代码就是在不停的分,之后的合并怎么办呢?但后面发现,虽然每一次是通过递归调用进行在分组,看似好像一次次在切块,但是本质上还是在对原有的数组上进行切分并进行调整排序,每次在变动的是数组中的索引在进行变动,好像是再切分的一样,然后再合并。但实质上其实还是在数组上,而不是像归并排序那样子,每次就切除然后直到不可以切除的时候,然后再对数组进行合并,此时才进行排序。而快排是在自己切分的时候就进行排序了,是一点点把排序大的范围,满满缩减,直到切分到不能再切,而这个时候左边的数肯定大于分界值,右边肯定小于等于分界值这个样子了。即然后分组排完序,有序了,然后加上分界值拼上就肯定也有序了
复杂度分析
版权声明:本文为qq_46627574原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。