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)。
相关推荐
野犬寒鸦15 分钟前
今日面试之快问快答:Redis篇
java·数据库·redis·后端·缓存·面试·职场和发展
渣哥21 分钟前
从对象头到内存屏障:synchronized 如何实现原子性、可见性与有序性
java
考虑考虑26 分钟前
时间转换格式出现错误
java·后端·java ee
乘风破浪酱5243630 分钟前
实战排查:如何从Nginx配置中顺藤摸瓜找到Java应用的真实端口与日志位置
后端
꧁༺摩༒西༻꧂37 分钟前
Flask
后端·python·flask
爱分享的鱼鱼38 分钟前
为什么使用express框架
前端·后端
程序员清风39 分钟前
字节三面:微博大V发博客场景,使用推模式还是拉模式?
java·后端·面试
郭老二1 小时前
【JAVA】从入门到放弃-03:IDEA、AI插件、工程结构
java·开发语言·intellij-idea
tqs_123451 小时前
多sheet excel 导出
java·开发语言·servlet
笨蛋不要掉眼泪1 小时前
SpringBoot项目Excel模板下载功能详解
java·spring boot·后端·spring·excel·ruoyi