package cn.com.dom4j.sort;

public class QuickSort {

/**

快速排序

在 Java中, 快速排序被用作基本数据类型的排序 (当然, 不只快速排序一种)

快速排序是实践中的一种快速的排序算法, 在 C++或对 Java基本类型的排序证特别有用.

它的平均运行时间是 O(N logN), 该算法之所以特别快, 主要是由于非常精炼和高度优化的内部循环.

它的最坏情形性能为 O(N^2), 但经过稍许努力可是这种情形极难出现.

通过将快速排序和堆排序结合, 由于堆排序的 O(N logN)最坏情形运行时间, 我们可以对几乎所有的输入都能达到快速排序的快速运行时间

*/

public static > void quickSort(AnyType[] a) {

quickSort(a, 0, a.length - 1);

}

/**

* 快速排序主例程

*

* @param a 原始数组

* @param left 起始索引

* @param right 结束索引

* @param 实现了 Comparable接口的类或其子类

*/

private static > void quickSort(AnyType[] a, int left, int right) {

// 定义数组大小边界, 小于这个值时使用插入排序

int CUTOFF = 10;

// 数组元素较少的时候, 使用插入排序来获取更快的速度; 元素较多时, 使用快排

if (left + CUTOFF <= right) {

// 三数中值分割法产生枢纽元

AnyType pivot = median3(a, left, right);

// i: 比枢纽元小的元素起始索引; j: 大元素的起始索引

int i = left, j = right - 1;

for ( ; ; ) {

// 小元素指针不断向右推进, 直到找到比枢纽元大的元素

while (a[++i].compareTo(pivot) < 0) {

}

// 大元素指针向左推进, 遇到比枢纽元小的元素终止

while (a[--j].compareTo(pivot) > 0) {

}

// 两个索引未交叉时, 代表大小序列还未分割完成, 交换位置后继续分割

// 交叉时代表分割完成

if (i < j)

swap(a, i, j);

else

break;

}

// 分割完成后, 将枢纽元和小元素索引终止处的元素位置互换

// 此时, 枢纽元左侧都为小元素, 右侧都为大元素 (相对于枢纽元而言)

swap(a, i, right - 1);

// 对分割后的子序列重复上面操作

quickSort(a, left, i - 1);

quickSort(a, i + 1, right);

} else {

insertionSort(a, left, right);

}

}

/**

* 对数组的指定部分使用插入排序

* @param a 原始数组

* @param left 起始索引

* @param right 结束索引

* @param 实现了 Comparable接口的类型或其子类

*/

private static > void insertionSort(AnyType[] a, int left, int right) {

if (right - left == 0 || left < 0 || right > a.length - 1) {

return;

}

AnyType tmp;

int j;

for (int i = left + 1; i <= right; i++) {

tmp = a[i];

for (j = i; j > left && tmp.compareTo(a[j - 1]) < 0; j--) {

a[j] = a[j - 1];

}

a[j] = tmp;

}

}

/**

三数中值分割法

使用左端, 右端和中心位置上的三个元素的中值作为枢纽元

*/

private static > AnyType median3(AnyType[] a, int left, int right) {

int center = (right - left) / 2;

// 对左中右三个位置的元素位置进行调整

// 最小的元素被放在最左端, 最大的元素放在最右端, 中间的元素放在中间位置, 中间元素要作为枢纽元

if (a[center].compareTo(a[left]) < 0) {

swap(a, left, center);

}

if (a[right].compareTo(a[left]) < 0) {

swap(a, left, right);

}

if (a[right].compareTo(a[center]) < 0) {

swap(a, center, right);

}

// 将枢纽元和右端倒数第二个元素交换位置, 使枢纽元离开数组, 便于元素比较

swap(a, center, right - 1);

// 将枢纽元返回

return a[right - 1];

}

/**

* 交换数组中两个元素的位置

*/

private static > void swap(AnyType[] arr, int i, int j) {

if (arr == null || arr.length <= 1 || i == j) {

return;

}

AnyType tmp = arr[i];

arr[i] = arr[j];

arr[j] = tmp;

}

}

Java排序算快速排序_Java排序算法 [快速排序]相关推荐

  1. java经典50题_JAVA经典算法50题(3)【面试+工作】

    原标题:JAVA经典算法50题(3)[面试+工作] JAVA经典算法50题(3)[面试+工作] [程序21] 题目:求1+2!+3!+...+20!的和. 1.程序分析:此程序只是把累加变成了累乘. ...

  2. python快速排序函数_python算法-快速排序

    快速排序: 学习快速排序,要先复习下递归: 递归的2个条件: 1. 函数自己调用自己 2.有一个退出的条件 练习:基于递归下一个函数,计算n!并且求出当n等于10的值. n!=n * n-1*-..* ...

  3. java g1 详解_JAVA垃圾收集算法总结以及CMS、G1算法详解

    前段时间由于工作原因一直很忙,上周项目验收后时间终于空闲下来,博客也有好几个月没有更新了,趁着还有几天放假,借这个机会写点东西:网上也有很多人写过Java垃圾收集器,特别现在主流比较火的CMS和G1算 ...

  4. java求公式例题_JAVA经典算法40题

    1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...

  5. java日期算前一天_java 根据系统日期获取前一天、后一天时间(根据初始日期推算出期望(向前/向后)日期)...

    1.情景展示 java 根据系统当前日期获取前一天日期.后一天日期,或者根据初始日期推算出期望(向前/向后)日期. 2.解决方案 导包 import java.text.ParseException; ...

  6. java题算工资_Java模版方法的小练习——工资系统

    题目要求 解题思路 1.一共涉及了5个类,父类是Employee,父类中有个属性定义的是MyDate类的对象,存储的是生日信息.两个子类HourlyEmployee.SalariedEmployee代 ...

  7. java 二维数据结构_JAVA描述算法和数据结构(01):稀疏数组和二维数组转换

    一.基本简介 1.基础概念 在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵:与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵.定义非零元 ...

  8. C语言快速排序 quick sort 算法(附完整源码)

    快速排序 quick sort 算法 快速排序 quick sort 算法的完整源码(定义,实现,main函数测试) 快速排序 quick sort 算法的完整源码(定义,实现,main函数测试) # ...

  9. 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...

    先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...

最新文章

  1. 使用PHP对数据库输入进行恶意代码清除
  2. linuxmessage日志消失_某工的centos7 启动了rsyslog之后,日志/var/log/messages等都不产生日志了,都是空的。求大神解决!...
  3. Windows多线程编程总结
  4. postgresql中装gis插件_Postgresql 空间扩展需要Postgis插件
  5. 关于wordpress中更换CKEditor编辑器
  6. python数据处理常用函数_pandas数据分析常用函数总结大全:上篇
  7. Cocopods的升级错误解决
  8. noise函数的使用
  9. LBS由ip查经纬度
  10. navicat无法连接mysql
  11. *第6章 判别分析及R使用
  12. EIGRP路由协议的简单理解及应用
  13. 中信建投软件测试,中信建投笔试经验-范例
  14. 查看U盘是USB2.0还是USB3.0
  15. java前后端分离,前端部署的方式
  16. Twaver-HTML5基础学习(38)劈分面板SplitPane
  17. (纪中)3505. 积木【DP】
  18. 联合循环——13(智慧电厂的发展与展望)
  19. kylin如何支持flink_Flink 在快手实时多维分析场景的应用
  20. input框点击时去掉默认的外层边框

热门文章

  1. C++ 异常 与 ”为什么析构函数不能抛出异常“ 问题
  2. C++中的继承与虚函数各种概念
  3. 在Windows下如何安装Tomcat服务器搭建
  4. 安装mysql显示有5.0_安装MySQL5.0时到如图这一步提示出错了,~
  5. android 字符串对齐,android – 使用Spanable String对齐ImageSpan
  6. Ios9 html5,ios9,html5_ios9下在浏览器中通过scheme打开app的问题,ios9,html5 - phpStudy
  7. AUTOSAR专业知识篇(六)-自动驾驶传感器的选择与布置
  8. oracle exp 00006,Oracle 12.1新特性----使用RMAN从备份中实现recover table
  9. ifram 表单post 方法免密登录的实现
  10. 从WEB应用的角度,一个应用都需要维护一些不同作用范围的状态, 请问下面哪些状态作用域是WEB应用特有的:( )