Java默认的排序算法 TimSort

Collections.sort()Arrays.sort() 的默认排序算法是基于 TimSort 的混合排序算法。TimSort 是一种结合了 归并排序(Merge Sort)插入排序(Insertion Sort) 的优化算法。


1. TimSort 的核心思想

TimSort 的核心思想是 利用数据的局部有序性,通过以下步骤实现高效排序:

  1. 分块(Run)

    • 将数组分成多个 有序的子数组(Run)
    • 如果子数组长度小于某个阈值(默认为 32),则使用插入排序将其扩展为更长的有序子数组。
  2. 合并(Merge)

    • 使用归并排序的合并方法,将多个有序子数组合并成一个有序数组。
    • 合并过程中,TimSort 会尽量利用已有的有序性,减少比较和移动的次数。

2. TimSort 的优势

  1. 适应性强

    • 对于部分有序的数据,TimSort 的性能接近 O(n)。
    • 对于随机数据,TimSort 的性能为 O(n log n)。
  2. 稳定性

    • TimSort 是稳定排序算法,相同元素的相对顺序不会改变。
  3. 空间复杂度

    • TimSort 的空间复杂度为 O(n),但在实际应用中,由于优化措施,额外空间通常较小。

3. Java 中的 TimSort 实现

在 Java 中,Collections.sort()Arrays.sort() 的默认排序算法是基于 TimSort 的。以下是相关源码的调用链:

  • Collections.sort()

    java 复制代码
    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }
  • List.sort()

    java 复制代码
    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }
  • Arrays.sort()

    java 复制代码
    public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }
  • TimSort.sort()

    • 这是 TimSort 的核心实现,负责分块、插入排序和归并排序。

4. TimSort 的适用场景

  1. 部分有序数据

    • TimSort 在部分有序数据上的性能优于传统的归并排序和快速排序。
  2. 稳定排序需求

    • 如果需要保持相同元素的相对顺序,TimSort 是一个理想选择。
  3. 通用排序

    • 由于 TimSort 的综合性能优异,Java 将其作为默认排序算法。

5. TimSort 的时间复杂度

情况 时间复杂度
最好情况 O(n)
最坏情况 O(n log n)
平均情况 O(n log n)

~~Summary

  • Java 的 Collections.sort()Arrays.sort() 默认使用 TimSort 算法。
  • TimSort 是一种结合了归并排序和插入排序的混合算法,具有稳定性和高效性。
  • 它在部分有序数据上的性能接近 O(n),在随机数据上的性能为 O(n log n)。
相关推荐
毕设源码-钟学长1 分钟前
【开题答辩全过程】以 农村困境儿童帮扶助学系统为例,包含答辩的问题和答案
java·eclipse
无限进步_2 分钟前
C语言宏的魔法:探索offsetof与位交换的奇妙世界
c语言·开发语言·windows·后端·算法·visual studio
白露与泡影2 分钟前
springboot中File默认路径
java·spring boot·后端
heartbeat..8 分钟前
使用 Apache POI 实现 Excel 文件读写(导入 导出)操作的工具类
java·apache·excel·文件
咕咕嘎嘎102420 分钟前
C/C++内存对齐
java·c语言·c++
认真敲代码的小火龙21 分钟前
【JAVA项目】基于JAVA的图书管理系统
java·开发语言·课程设计
汝生淮南吾在北26 分钟前
SpringBoot+Vue游戏攻略网站
前端·vue.js·spring boot·后端·游戏·毕业设计·毕设
西岭千秋雪_27 分钟前
MySQL日志梳理(存储引擎层)
java·数据库·分布式·mysql·oracle
2301_7973122627 分钟前
学习Java22天
java·开发语言
IMPYLH35 分钟前
Lua 的 type 函数
开发语言·笔记·后端·junit·lua