TimSort算法分析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TimSort算法分析相关的知识,希望对你有一定的参考价值。

Timsort是一种混合稳定的排序算法,采用归并排序混合插入排序的设计,在多种真实数据上表现良好。

它基于一个简单的事实,实际中大部分数据都是部分有序(升序或降序)的。

它于2002年由Tim Peters在Python编程语言实现。

Timsort排序算法中定义数组中的有序片段为run,每个run都要求单调递增或严格单调递减(保证算法的稳定性),如下图:

文中图片都是我手绘的,字写的难看了点,将就看吧~

技术分享

 

Timsort排序算法可以概括成两步:

1. 把待排序数组分成一个个的run(即单调上升的数组), 并且run不能太短, 如果run的长度小于minRun这个阀值, 则使用插入排序进行填充

2. 将上面的一个个run入栈, 当栈顶的run的长度不满足下列约束条件中的任意一个时,则使用归并排序将其中最短的2个run合并成一个新的run,最终栈=1的时候,排序完成。

  ① runLen[n-2] > runLen[n-1] + runLen[n]

  ② runLen[n-1] > runLen[n]

 

下面用一个例子进行说明,假设minRun=5,也就是说run的最小长度不能小于5,如果小于5则使用插入排序进行填充。每划分出一个run就将其入栈,如下图所示:

技术分享

注意:此时栈顶的run是不满足约束条件的,因为此时runLen[0] < runLen[1],所以要对这两个run进行归并,这个过程使用的是归并排序。

如果遇到run的长度小于minRun的情况,则需要进行填充,直到run的长度=minRun或者数组结束为止,如下图:

技术分享

至此排序完成~~~有的同学可能会有疑问,为什么要有那个奇怪的约束条件呢?每次入栈的时候直接进行归并不行吗?这主要是考虑到归并排序的效率问题,

因为将一个长序列和一个短序列进行归并排序从效率和代价的角度来看是不划算的,而两个长度均衡的序列进行归并排序时才是比较合理的也比较高效的。

这里只是简单的阐述了一下TimSort的思想原理,具体实现还是有很多细节需要考虑的,下一篇文章会分析JDK1.8中TimSort的代码实现~

 

最后来一张归并排序的动态图片:

技术分享

 

以上是关于TimSort算法分析的主要内容,如果未能解决你的问题,请参考以下文章

一文了解 Python 中的 Timsort 排序算法

java.util.ComparableTimSort中的sort()方法简单分析

简易版的TimSort排序算法

jdk8源码TimSort算法——从头看到脚

jdk8源码TimSort算法——从头看到脚

Timsort排序算法