一 简单介绍
Timsort是一个最好时间复杂度可以达到O(n),最坏为O(nlgn),平均为O(nlgn)的算法。Java里基本数据类型是用快排的,但是对于引用类型的排序是Timsort和二分插入排序结合的。当数据大小<32的时候用二分插入排序,>32时候用TimSort。
TimSort是一个插入排序和归并排序结合的算法,我们知道归并排序,把一个序列分成两半,分别排序成有序的子序列之后,再合并,这就有一个问题,分成的两半是直接就把长度分成了两半,如果正好把有序的连续段给分开了,不就浪费了这有序的性质吗?TimSort也是分,但是TimSort是利用现实中的数据大多是部分有序的特点来分。TimSort思想非常的简单:
(1)将数组按连续递增或者递减分成一个个分区,称为run。(如果是递减,直接倒置为递增的)
(2)将这些run合并。
二 Timsort详解
下面分析Timsort的细节
(1)关于run的最小长度:
run的长度有限制,run的长度必须大于一个值,这个值称为minrun:
① 如果数组的长度本身就小于一个值,则这个值就是minrun,只需要对其进行二分插入排序。(这个值Tim Peters给的C源码中设为64,在java里设为32,下面均以32为例)
②如果数组长度>32:
为了提高合并的效率,需要run的个数等于或略小于2的幂,minrun长度范围取[16,32],m