南风娱乐网致力于优质软件,活动线报,游戏辅助,绿色工具等资源共享,好货不私藏!
精品资源,免费分享

快速排序图解(快速排序算法的原理图解)

作者:南风

之前我们介绍了交换排序中的冒泡排序,这次我们介绍了另一种交换排序,叫做快速排序。快速排序的优点是排序到位,不占用额外的空 room,时间复杂度为O(nlogn)。

当然,对于快速排序来说,它也有缺点。对于有大量重复元素的数组排序效率非常低,时间复杂度会降低到O (n 2)。这时候就需要使用改进的快速排序——双向快速排序。在双向快速排序的基础上,我们进一步优化了三向快速排序。

快速排序

快速排序的基本思想是:通过一次排序,把要排序的数据分成两个独立的部分,其中一部分的所有数据小于另一部分的所有数据,然后按照这种方法对这两部分数据进行快速排序。整个排序过程可以递归进行,使整个数据成为有序序列。

快速排序的步骤如下:

1.以第一个元素为分界点,用l指向它。

快速排序图解(快速排序算法的原理图解)

2.遍历右边的元素。在遍历的过程中,我们对数组进行排序,有些小于V,有些大于V,J指向小于V和大于V的边界点,I指向当前访问的元素e,此时数组arr

3.如果E >: V,那么在大于V的部分之后直接合并E,然后i++会继续比较后面的元素。

快速排序图解(快速排序算法的原理图解)

4.如果E < V,那么将E移动到J指向的元素的下一个元素,然后j++,然后i++继续比较后面的元素。

快速排序图解(快速排序算法的原理图解)

5.使用此方法遍历整个数组一次。遍历后,数组分为三部分,左边部分是V,中间部分是>:V,右边部分是

快速排序图解(快速排序算法的原理图解)

6.最后我们把L指向的元素和J指向的元素互换,这样元素V就排序很快了。V左边的元素都小于V,右边的元素都大于V。

快速排序图解(快速排序算法的原理图解)

现在我们用上面的方法来比较这个数组

快速分类代码:

公共静态空排序(可比较的

上面,我们使用左边的第一个元素作为校准元素。现在,我们随机选择一个元素作为校准元素。此时,第一次选择第一个元素的概率为1/n,第二次选择第二个元素的概率为1/n-1,以此类推。在它发生之前退化成链表的概率是1/n(n-1)(n-2)& # 8230;。,当n较大时,这个概率几乎为零。

另一个优化是对小规模数组使用插入排序,因为递归会让小规模问题中方法的调用过于频繁,而插入排序对于小规模数组来说速度非常快。

优化的快速分类代码:

公共静态空排序(可比较的

2.从I开始向后遍历,如果遍历的元素e < V,继续向后遍历,直到遍历的元素e >: =v,遍历停止。从j向前遍历,如果被遍历的元素e >: V,继续向前遍历,直到被遍历的元素e

快速排序图解(快速排序算法的原理图解)

3.交换I指向的元素和J指向的元素。然后i++,j & # 8211继续对比下一个。

快速排序图解(快速排序算法的原理图解)

双向快速分类代码:

公共静态空排序(可比较的

2.从I向后遍历,如果遍历的元素e=v,那么E直接合并到=v部分,然后i++继续遍历。如果遍历的元素e : V,那么e和>:Part v交换前面的元素(gt-1指向的元素),然后gt & # 8211但此时不需要更改I,因为I位置的元素与gt位置前面的空 white元素进行了交换。

3.遍历后,i=gt,然后把L指向元素和lt指向元素交换。

快速排序图解(快速排序算法的原理图解)

4.右< Part v sum >: Part v做上面的操作。

与双向快速排序相比,三向快速排序的优点是减少了重复元素的比较操作,因为重复元素在一次排序中已经被排列为单个部分,然后只需要对不等于重复元素的其他元素进行排序。

三向快速分类代码:

公共静态void排序(Comparable[] arr) {

int n = arr.length

sort(arr,0,n & # 82111);

}

私有静态void排序(Comparable[] arr,int l,int r) {

//对于小规模数组,使用插入排序

如果(r & # 8211l & lt= 15) {

InsertionSort.sort(arr,l,r);

返回;

}

//在arr[l & # 8230;R],选择一个数值作为校准点枢轴。

swap(arr,l,(int)(*th . random()*(r & # 8211;l+1))+l);

可比v = arr[l];

int lt = l;//arr[l+1 & # 8230;lt]& lt;v

int gt = r+1;//arr[gt & # 8230;r]& gt;v

int I = l+1;//arr[lt+1 & # 8230;i) == v

while(我& ltgt) {

if (arr[i]。compare to(v)& lt;0) {

swap(arr,I,lt+1);

i++;

lt++;

} else if (arr[i]。compare to(v)gt;0) {

swap(arr,I,gt & # 82111);

gt & # 8211;

} else { // arr[i] == v

i++;

}

}

swap(arr,l,lt);

sort(arr,l,lt & # 82111);

sort(arr,gt,r);

}

摘要

介绍了快速排序、快速排序优化、双向快速排序和三向快速排序。

对于快速排序,我们需要选择合适的校准点,使校准点两侧平衡;在快速排序中递归到一个小数组时,我们可以用插入排序代替递归来减少不必要的开销。

对于双向快速排序和三向快速排序,当数组中有大量重复元素时,我们使用它。

最后建议JDK的底层排序采用插入排序+双向快速排序+归并排序的组合。

免责声明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络收集整理,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解!

最新评论