当前位置: 首页 > news >正文

【Java】Arrays.sort:TimSort

一,概述

书接前文【Java】Arrays.sort:DualPivotQuicksort-CSDN博客

Arrays.sort对基本数据类型使用了双轴快速排序,但是对Object[]类型,则使用了TimSort,TimSort是稳定的排序,它整合了插入排序+归并排序,存在空间换时间策略,本文简单解析下此算法实现。

二,实现

入口,Object[]调用Arrays.sort方法

sort内部根据配置策略,使用旧版归并排序,或TimSort,

进入第二个分支,以下sort算法即TimSort,本篇文章分析核心。

TimSort是插入排序+归并排序结合的算法,兼顾了两种排序的优点,比如插入排序时间复杂度最优可以达到O(N),但最差O(N^2)。归并排序是稳定排序,时间复杂度是O(NLogN),空间复杂度O(N),TimSort结合了两种排序优缺点,时间复杂度在O(N)~O(NLogN),空间复杂度是O(N)。

此sort算法分步骤进行如下:

1,计算序列最小分块长度

2,对序列分块进行线性扫描,得到N块有序序列

3,对有序序列进行合并

4,当有序序列最后只剩1块,排序完成,

接下来,看下java内部实现

1,拿到序列size,保存至nRemaining,表示剩余序列长度

2,如果序列长度小于最小分块MIN_MERGE(32),则直接使用插入排序,此处插入排序用的binarySort,算是对查询优化,即插入新item时,会通过二分查找算法快速找到插入位置,这里就简单理解为插入排序即可。

当nRemaining >= MIN_MERGE时,开始计算最小分块个数

minRunLength是返回最小分块长度,由以上注释知,

minRunLength = n (n < MIN_MERGE) or 

MIN_MERGE/ 2 <= minRunLength <= MIN_MERGE,使得得到的序列个数n/k接近2的幂数,

此处不赘述

下一步,对最小分块进行排序,

1,线性扫描一遍,简单将指针经过序列排序,

2,如果得到的runLen长度(已有序块)< 最小分块长度,则调用插入排序重新排序,否则就忽略,

这个runLen可能是1,也可能是整个序列长度(序列原本有序),经过以上步骤,会将原序列分成N个有序序列,

下一步,将扫描有序序列入栈,并且合并,如下

栈使用数组记录,保存了每个分块的起点位置和长度,

mergeCollapse可能对stack中分组进行合并,合并算法不赘述,

最后,当整个序列合并完成后,stack中只存在一个序列,done

相关文章:

  • 560. 和为K的子数组
  • 软件测试之APP测试要点(包含Monkey基础使用)
  • C++实现文本编辑功能
  • C primer plus (第六版)第七章 编程练习第4题,第5题
  • 企业如何高效构建BI团队,解锁数据价值新高地?
  • 解锁Wi-SUN潜能!移远通信发布KCM0A5S模组,点亮智慧城市新图景
  • 利用递归来遍历树
  • 蛋糕烘焙小程序源码介绍
  • 阿糖胞苷联合伊达比星为代表的强化治疗方案引领AML多阶段治疗新进展
  • UFS-Ver3.1-第九章
  • docker 安装postgre并使用php进行连接
  • Nextcloud的性能提升3倍的部署说明:你的nextcloud需要重新部署了
  • day64—回溯—组合数(LeetCode-77)
  • Verilog:流水线乘法器
  • Unity Android 启动应用的时候黑屏问题
  • 关于亚马逊WOOT折扣力度
  • 【沉浸式解决问题】csdn无法发布文章
  • 最长和谐子序列
  • 常见无法用初等函数表示的不定积分(表格总结)
  • 数据隐私是什么?如何做好数据隐私规范?
  • 视频背景做网站背景/网络营销案例分析
  • 阿里云网站建设 部署与发布答案/徐州自动seo
  • 浙江五联建设有限公司网站/深圳百度推广客服电话多少
  • 河南省住房城乡建设门户网站/合肥网站排名提升
  • 东莞wordpress/seo在线论坛
  • 广告片拍摄的具体流程/c盘优化大师