http://book.douban.com/annotation/15154366/
Q: java.util.Arrays 中使用的 sort 采用的是什么算法?
 
A: java中Arrays.sort使用了两种排序方法,quick sort 和优化的 merge sort。
 
Q: 为什么采用两种排序算法?
 
A: quick sort 主要是对哪些基本类型数据(int, short, long, float, double等)排序, 而 merge sort 用于对对象类型进行排序。
 
Q: quick sort 在统计意义上效率比 merge sort 高,为何不都采用 quick sort ?
 
A: 概括的说,一个是稳定性,一个是移动次数。使用不同类型的排序算法主要是由于 quick sort 是不稳定的,而 merge sort 是 stable 的。这里的 stable 是指比较相等的数据在排序之后仍然按照排序之前的前后顺序排列(保序性)。对于基本数据类型,稳定性没有意义。而对于对象类型,稳定性是比较重要的,因为对象相等的判断可能只是判断关键属性,最好保持相等对象的非关键属性的顺序与排序前一直;另外一个原因是由于合并排序相对而言比较次数比快速排序少,移动(对象引用的移动)次数比快速排序多,而对于对象来说,比较一般比移动耗时。
 
merge sort
 
(1)最坏时间复杂度是 O(nlgn);
 
(2)平均时间复杂度是 O(nlgn);
 
(3)空间复杂度是 O(1)。
 
quick sort
 
(1)最坏时间复杂度是 O(n^2);
 
(2)平均时间复杂度是 O(nlgn);
 
(3)空间复杂度是 O(n)。
 
验证了一下 java.util.Arrays.sort(arrayName) 的时间复杂度,程序如下:
 
  1. /* constant variables */
  2. final int NUM = 10;
  3. final int OFFSET = 2;
  4. final int LOOP = 100000;
  5. /* arrays */
  6. int[][] array = new int[NUM][];
  7. long[] start = new long[NUM];
  8. long[] end = new long[NUM];
  9. long[] cost = new long[NUM];
  10. /* initialization */
  11. for (int i = 0; i < array.length; ++i) {
  12. array[i] = new int[1 << (i * OFFSET)];
  13. }
  14. for (int i = 0; i < array.length; ++i) {
  15. for (int j = 0; j < array[i].length; ++j) {
  16. array[i][j] = (int)(Math.random());
  17. }
  18. }
  19. /* sorting */
  20. for (int count = 0; count < LOOP; ++count) {
  21. for (int i = 0; i < array.length; ++i) {
  22. start[i] = System.currentTimeMillis();
  23. Arrays.sort(array[i]);
  24. end[i] = System.currentTimeMillis();
  25. cost[i] += end[i] - start[i];
  26. }
  27. }
  28. /* output */
  29. for (int i = 0; i < cost.length; ++i) {
  30. System.out.println(
  31. "n = " + array[i].length +
  32. ", time = " + cost[i] / 1000.0
  33. );
  34. }
 
对不同规模n的数组,分别进行10万次排序,统计10万次排序的总时间,结果如下:
 
n = 1, time = 0.013s
 
n = 4, time = 0.011s
 
n = 16, time = 0.029s
 
n = 64, time = 0.066s
 
n = 256, time = 0.198s
 
n = 1024, time = 0.797s
 
n = 4096, time = 3.005s
 
n = 16384, time = 12.101s
 
n = 65536, time = 48.101s
 
n = 262144, time = 192.174s
http://book.douban.com/annotation/15154366/

[Java] java.util.Arrays 中使用的 sort 采用的算法 (转)的更多相关文章

  1. 源码(09) -- java.util.Arrays

    java.util.Arrays 源码分析 ------------------------------------------------------------------------------ ...

  2. java:数组操作工具类 java.util.Arrays包 主要方法详解

    Arrays类位于Java.util包下,是一个对数组操作的工具类,现将Arrays类中的方法做一个总结(JDK版本:1.6.0_34).Arrays类中的方法可以分为八类: sort(对数组排序) ...

  3. JDK源码(1.7) -- java.util.Arrays

    java.util.Arrays 源码分析 ------------------------------------------------------------------------------ ...

  4. java 中java.util.Arrays类---常用函数记录

    java.util.Arrays主要是用来对数组进行操作的类,主要包括以下方法: 1.数组转化列表,得到固定大小的列表,Arrays.asList(...): public static <T& ...

  5. Java中数组操作 java.util.Arrays 类常用方法的使用

    任何一门编程语言,数组都是最重要和常用的数据结构之一,但不同的语言对数组的构造与处理是不尽相同的. Java中提供了java.util.Arrays 类能方便地操作数组,并且它提供的所有方法都是静态的 ...

  6. Java找N个数中最小的K个数,PriorityQueue和Arrays.sort()两种实现方法

    最近看到了 java.util.PriorityQueue.刚看到还没什么感觉,今天突然发现他可以用来找N个数中最小的K个数. 假设有如下 10 个整数. 5 2 0 1 4 8 6 9 7 3 怎么 ...

  7. java.util.Arrays的使用

    在Java.util包中有一个工具类Arrays类,封装了一些操作数组的方法.简单使用如下: package com.arrays.test; import java.util.Arrays; pub ...

  8. Java 数组基础,java.util.Arrays

    定义数组 方式1(推荐,更能表明数组类型) 方式2(同C语言) 方式3定义时直接初始化 数组运用基础 数组长度 equals() 数组元素不为基本数据类型时 二维数组 二维数组基础 变长的二维数组 j ...

  9. JDK1.8源码(四)——java.util.Arrays 类

    java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用. 1.asList public static ...

随机推荐

  1. ASP.NET MVC中的Global.asax文件

    1.global.asax文件概述 global.asax这个文件包含全局应用程序事件的事件处理程序.它响应应用程序级别和会话级别事件的代码. 运行时, Global.asax 将被编译成一个动态生成 ...

  2. 无废话Android之内容观察者ContentObserver、获取和保存系统的联系人信息、网络图片查看器、网络html查看器、使用异步框架Android-Async-Http(4)

    1.内容观察者ContentObserver 如果ContentProvider的访问者需要知道ContentProvider中的数据发生了变化,可以在ContentProvider 发生数据变化时调 ...

  3. ExcelReport第一篇:使用ExcelReport导出Excel

    导航 目   录:基于NPOI的报表引擎——ExcelReport 下一篇:ExcelReport源码解析 概述 本篇将通过导出学生成绩的示例演示“使用ExcelReport导出Excel”的步骤. ...

  4. HDU1502 Regular Words

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1502 思路:当只有两个数时,可以用卡特兰数做,当三个数时,没想到卡特兰数的做法.可以使用动态规划. 状态转 ...

  5. 攻城狮在路上(叁)Linux(十五)--- 文件与目录的默认权限与隐藏权限

    一.文件默认权限:umask <==需要被减去的权限. 1.umask指的是当前用户在新建文件或者目录时的默认权限,如0022; 2.默认情况下,用户创建文件的最大权限为666; 创建目录的最大 ...

  6. golang debug with LiteIDE

    golang 的调试比较麻烦,debug stop into 无法跳转到自己写的代码,但是能够跳转到系统提供的代码. 以下是简单的测试代码: package main import ( "f ...

  7. NSDate用法整理总结

    int main(int argc, const char * argv[]) { @autoreleasepool { NSDate *date=[NSDate date]; NSLog(@&quo ...

  8. Android自动化压力测试之Monkey Test Android常见的错误类型及黑白名单的使用方法(四)

    Android常见的错误类型有两种 1.ANR类型 1)在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸) 2)BroadcastReceiver在10秒内没有执行完毕 2.Crash类型 1)异 ...

  9. LoadRunner常见函数分析

    LoadRunner常见函数分析 ?%Ze\N%?~"_J}.t051Testing软件测试网;FQ X%L|GO+R Web用户Action51Testing软件测试网b,Q8iO w1j ...

  10. 开发Portlet第二步:如何将Crystal静态Portlet转变成基于测试数据的动态Portlet?

    当基于Crystal的静态Portlet开发完成后,在与后台服务联调前,还需要将Portlet转换成基于测试数据的动态Portlet.具体步骤如下: 分步指南 复制Portlet项目,并修改相关的po ...