Java实现快速排序(二)
来源:互联网 发布:crm软件系统 编辑:程序博客网 时间:2024/06/04 00:53
快速排序是一种分治法的思想,主要思想是首先找一个“基准”元素,将所有比基准元素大的元素放到基准元素右边,所有比基准元素小的元素放到基准元素左边,这样基准元素在整个序列中的最终位置就确定了,同时,基准元素经序列分为两个子序列,对子序列进行上述同样的操作,最终就能得到有序的序列。
package 排序算法;public class 快速排序二 {public static void main(String[] args) {int[] a = { 21, 3, 324, 23, 534, 5, 34 };quickSort(a, 0, a.length - 1);for (int i = 0; i < a.length; i++) {System.out.println(a[i] + " ");}}// 快速排序private static void quickSort(int[] a, int left, int right) {int split_point;if (left < right) {split_point = partition(a, left, right);quickSort(a, left, split_point - 1);quickSort(a, split_point + 1, right);}}/** * 以第一个元素为基准,将元素分成左右两部分,左边的都比基准小,右边的都比基准大。 返回基准位置 * * @param a * @param left * @param right * @return */private static int partition(int[] a, int left, int right) {int i = left, j = right, pivot = a[left]; // 以第一个元素为基准while (i < j) {for (; i < j && a[j] >= pivot; j--); // 从右边找一个比pivot小的数a[i] = a[j]; // 将这个数放到左边空位,空位是由pivot或之前比pivot大的数留出来的for (; i < j && a[i] < pivot; i++); // 从左边找一个比pivot大的数a[j] = a[i]; // 将这个数放到右边空位}a[i] = pivot;return i;}}
partition函数的功能就是将整个序列分成左右两部分,中间是基准元素的最终位置,这个函数分别从右边j和左边i开始找,总的比较次数为子序列的长度-1,(第一个是pivot不用比较),且i<=j,所以partition复杂度为O(n)。
最坏情况:当整个序列是正序的时候,这样每次递归将序列分成两个子序列时,第一个序列只有一个元素,第二个序列有n-1个元素,而每次递归的非递归代价(partition的代价,比较次数)为子序列的长度-1,总的比较次数为:(n-1)+(n-2)+...+1=n(n-1)/2,所以时间复杂度为O(n^2)。
平均情况:假设划分点(pivot的最终位置)在每个位置的概率是相等的。这时快速排序的递归表达式为:
其中(n-1)表示非递归代价(partition代价),可以注意到对T(i)和T(n-1-j)从i=0到n-1求和是相等的,所以递归表达式最终转化为:
,通过数学归纳法可以证明T(n)的复杂度为O(nlgn)。
最终结算结果为:T(n)约等于。
快速排序的4种优化:(详见下一篇快排的三种实现以及四种优化方式)
优化1:当待排序序列的长度分割到一定大小后,使用插入排序
优化2:在一次分割结束后,可以把与Key相等的元素聚在一起,继续下次分割时,不用再对与key相等元素分割
优化3:优化递归操作
优化4:使用并行或多线程处理子序列
0 0
- Java实现快速排序(二)
- 简单排序Java实现(二):归并排序,快速排序
- 程序员必知的8大排序(二)-------冒泡排序,快速排序(java实现)
- Java 实现 堆排序 快速排序 以及 TopK问题(二)
- 快速排序实现(JAVA)
- 快速排序(java实现)
- 快速排序(java实现)
- 快速排序(java实现)
- 快速排序实现(Java)
- 快速排序(java实现)
- 快速排序(java实现)
- 快速排序(Java实现)
- 排序算法总结(二)-------选择,堆,冒泡,快速,归并排序(java实现)
- Java实现数组的快速排序(快速排序算法)
- java实现快速排序
- 快速排序Java实现
- 快速排序java实现
- 快速排序JAVA实现
- 2016.10.05【GaoJueYi 初中部 NOIP普及组 】模拟赛总结及8、9月总结
- Android几种进程
- 20161005
- 四元数与欧拉角之间的转换及程序源码
- ios 简单的使用按比例自适应屏幕
- Java实现快速排序(二)
- APP启动过程
- SSDsim源码分析之pre_process_page
- 进程死锁及解决方式
- 初尝Fresco
- Android图片中的三级缓存
- Handler消息传递机制学习
- 使用nodejs实现类似于C语言的scanf输入一个动态数组
- [LeetCode]--119. Pascal's Triangle II