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)。
相关推荐
qq_485015213 小时前
MyBatis-Plus 3.x FieldStrategy 作用
java·数据库·mybatis
lhldsg3 小时前
课程排课系统实战指南:从数据库设计到算法调优全流程解析
java·数据库·算法·小程序
光电的一只菜鸡3 小时前
高通tuning中eis需要调什么
java·开发语言·前端
API快乐传递者3 小时前
1688 跨境电商 API 接口实战指南:从寻源到代采的全链路技术方案
java·前端·数据库
孔明click333 小时前
不想写代码,但想要集成一个登录页面?Sa-Token-Quick-Login 帮你实现!
java·sa-token·开源·springboot·登录·权限·权限认证
马可家的菠萝4 小时前
收藏不是终点:一个真正有用的个人知识库,至少要完成“收集 → 理解 → 行动”
前端·后端·架构
曹牧4 小时前
C#与Java后台交互
java·windows·microsoft·c#
张晓祥-长草颜团子4 小时前
【重庆两江新区歌词】
java
东小西4 小时前
【SAA实战】第 2 篇:模型与消息——ReactAgent 怎么挑模型、怎么传消息
java·后端·spring
qo_tn4 小时前
Docker_02-容器操作_11-怎样进入容器执行命令
后端