一、基本概念
找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
二、选择基准元
固定基准元
如果输入序列是随机的,处理时间是可以接受的。如果数组已经有序时,此时的分割就是一个非常不好的分割。因为每次划分只能使待排序序列减一,此时为最坏情况,快速排序沦为冒泡排序,时间复杂度为Θ(n^2)。而且,输入的数据是有序或部分有序的情况是相当常见的。因此,使用第一个元素作为基准元是非常糟糕的,应该立即放弃这种想法。
随机基准元
这是一种相对安全的策略。由于基准元的位置是随机的,那么产生的分割也不会总是会出现劣质的分割。在整个数组数字全相等时,仍然是最坏情况,时间复杂度是O(n^2)。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2^n)。所以随机化快速排序可以对于绝大多数输入数据达到O(n×log(n))的期望时间复杂度。
三数取中
最佳的划分是将待排序的序列分成等长的子序列,最佳的状态我们可以使用序列的中间的值,也就是第N/2个数。可是,这很难算出来,并且会明显减慢快速排序的速度。这样的中值的估计可以通过随机选取三个元素并用它们的中值作为基准元而得到。事实上,随机性并没有多大的帮助,因此一般的做法是使用左端、右端和中心位置上的三个元素的中值作为基准元。
三、partition算法
partition算法是快速排序的核心,在学习快排之前,可以先学习一下这个算法。下面先贴代码:
public int partition(int[] num,int left,int right){ if(num==null || num.length<=0 || left<0 || right>=num.length){ return 0; } int prio=num[left+(right-left)/2]; //获取数组中间元素的下标 while (left<=right){ //从两端交替向中间扫描 while (num[left]<prio) left++; while (num[right]>prio) right--; if (left<=right){ swap(num,left,right); //最终将基准数归位 left++; right--; } } return left; }
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1148
183.71 KB下载数642
644.84 KB下载数2756
相关文章
发现更多好内容- Java 人脸识别具体有哪些应用场景呢?(Java人脸识别有哪些应用场景)
- JAVA 中如何运用 QT 来开发 GUI?(JAVA中怎么使用QT开发GUI)
- 如何在 MySQL 中优化插入大量数据的操作?(mysql insert大量数据时如何优化)
- 如何高效升级Redis客户端
- Java 中如何获取内存地址中的值?(java如何获取内存地址中的值)
- 在 Java 中,showdialog 的具体用法究竟是什么?(java中showdialog的用法是什么)
- 如何在 Java 中应用 Hyperscan 以及其具体场景有哪些?(Hyperscan在Java中的应用场景)
- 如何在 Java 中求二维数组的最大值?(java怎么求二维数组的最大值)
- Java 中 invoke 方法的作用究竟是什么?(java invoke方法的作用是什么)
- Java 代理模式常见的应用场景有哪些?(java代理模式的应用场景是什么)