java TimSort算法思路理解

文章目录

  • 前言
  • java doc介绍
    • 英文介绍
    • 含义
  • 思路
  • 参考资料

前言

今天线上环境报了个错:

java.lang.IllegalArgumentException: Comparison method violates its general contract! 
at java.util.TimSort.mergeHi(TimSort.java:899) ~[?:1.8.0_111] 
at java.util.TimSort.mergeAt(TimSort.java:516) ~[?:1.8.0_111] 
at java.util.TimSort.mergeCollapse(TimSort.java:441) ~[?:1.8.0_111] 
at java.util.TimSort.sort(TimSort.java:245) ~[?:1.8.0_111] 
at java.util.Arrays.sort(Arrays.java:1512) ~[?:1.8.0_111] 
at java.util.ArrayList.sort(ArrayList.java:1454) ~[?:1.8.0_111]

百度了下,ArrayList排序,1.7开始,使用TimSort进行排序。而TimSort增加了自反性检查,不满足自反性时,会报错。
TimSort的实现原理是什么,基于源码、结合网上的一些博文,自我理解并进行记录。

java doc介绍

英文介绍

A stable, adaptive, iterative mergesort that requires far fewer than n lg(n) comparisons 
when running on partially sorted arrays, 
while offering performance comparable to a traditional mergesort when run on random arrays. 
Like all proper mergesorts, this sort is stable and runs O(n log n) time (worst case). 
In the worst case, this sort requires temporary storage space for n/2 object references; 
in the best case, it requires only a small constant amount of space. 

This implementation was adapted from Tim Peters's list sort for Python, 
which is described in detail here: http://svn.python.org/projects/python/trunk/Objects/listsort.txt 
...

含义

一种稳定的、自适应的、迭代的合并排序,
在部分已排序的数组上运行时,时间复杂度远小于NLg(N),在随机数组上运行时性能开销和传统的合并排序相当。
和其他算法算法已有,本算法的表现是稳定的。
时间复杂度:最坏情况下为O(N
Lg(N));
空间复杂度:最坏情况为N/2,最好的情况为常数级。

算法实现,基于Tim Peters’s的Python版实现进行改编。原文地址:http://svn.python.org/projects/python/trunk/Objects/listsort.txt


思路

举个例子:
看书的方法,一种是看完所有章节,然后进行内容回顾;另一种是先看完第一章,回顾第一章,然后看完第二章,回顾第一章、第二章,将两章内容进行串联,接着按同样的方式看第三章、… 等,直到看完全书。

冒泡、归并排序等,采用的是第一种思路,一次性对数组内所有数据进行处理。
TimSort,主体思路,采用的是第二种,把一个大数组,分为N部分来处理。先对第一部分数据排序(即0/N - 1/N),然后对第二部分数据进行排序(即1/N - 1/N),接着有序合并第一部分、第二部分数据。同样道理,对第三部分、…、第N部分数据进行处理,最终输出排序后的结果。

TimSort在上述主体思路上,加入了一些处理手段。
如数组很小,不分步,一步处理到位(TimSort#binarySort);
对每一个部分的数据进行排序时,先识别有序部分并进行快速处理,然后对该部分剩余无序部分进行二分插入排序(TimSort#binarySort)

这个算法目的,个人理解:
真实情况下,需要排序的内容有各种各样的可能。如随机、部分有序(正序or反序)、已全部排序(正序or反序)。
为了提高排序效率,应对各种可能的场景,调整了实现逻辑,优化排序效率。


参考资料

https://blog.csdn.net/bruce_6/article/details/38299199

你可能感兴趣的:(术(知识点))