Java算法之TimSort

[复制链接]
发表于 2026-1-30 09:40:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
TimSort简介

TimSort是一种高效的排序算法,由Tim Peters于2002年计划,重要特点是连合了归并排序(Merge Sort)和插入排序(Insertion Sort)的优点。这种算法在很多编程语言的默认排序函数中得到应用,如Python的sort()和Java的Arrays.sort()。
算法原理

TimSort的工作原理如下:

  • 分解:将待排序数组分解为小的有序序列,每个序列长度为minrun。
  • 插入排序:对每个minrun巨细的小数组利用插入排序,由于小数组的插入排序非常高效。
  • 归并排序:递归地将有序序列归并成更大的有序序列,直到整个数组有序。
代码实现

以下是利用Java实现TimSort的示例代码
  1. public class TimSort {
  2.     private static final int MIN_RUN_SIZE = 32; // 定义最小运行大小
  3.     // 插入排序辅助函数
  4.     private static void insertionSort(int[] arr, int left, int right) {
  5.         for (int i = left + 1; i <= right; i++) {
  6.             if (arr[i] < arr[i - 1]) {
  7.                 int temp = arr[i];
  8.                 int j = i - 1;
  9.                 while (j >= left && arr[j] > temp) {
  10.                     arr[j + 1] = arr[j];
  11.                     j--;
  12.                 }
  13.                 arr[j + 1] = temp;
  14.             }
  15.         }
  16.     }
  17.     // 归并两个有序序列
  18.     private static void merge(int[] arr, int l, int m, int r) {
  19.         int n1 = m - l + 1;
  20.         int n2 = r - m;
  21.         // 创建临时数组
  22.         int[] L = new int[n1];
  23.         int[] R = new int[n2];
  24.         // 复制数据到临时数组
  25.         System.arraycopy(arr, l, L, 0, n1);
  26.         System.arraycopy(arr, m + 1, R, 0, n2);
  27.         // 合并临时数组回到原数组arr[l..r]
  28.         int i = 0, j = 0, k = l;
  29.         while (i < n1 && j < n2) {
  30.             if (L[i] <= R[j]) {
  31.                 arr[k++] = L[i++];
  32.             } else {
  33.                 arr[k++] = R[j++];
  34.             }
  35.         }
  36.         // 复制左数组中的剩余元素
  37.         while (i < n1) {
  38.             arr[k++] = L[i++];
  39.         }
  40.         // 复制右数组中的剩余元素
  41.         while (j < n2) {
  42.             arr[k++] = R[j++];
  43.         }
  44.     }
  45.     // 计算minrun
  46.     private static int calculateMinRun(int n) {
  47.         return (n | (n >> 1)) + 1;
  48.     }
  49.     // TimSort主函数
  50.     public static void timSort(int[] arr) {
  51.         int n = arr.length;
  52.         int minRun = calculateMinRun(n);
  53.         // 对每个minRun大小的序列进行插入排序
  54.         for (int i = 0; i < n; i += minRun) {
  55.             insertionSort(arr, i, Math.min(i + minRun - 1, n - 1));
  56.         }
  57.         // 逐步合并
  58.         for (int size = minRun; size < n; size *= 2) {
  59.             for (int left = 0; left < n; left += size * 2) {
  60.                 int mid = left + size - 1;
  61.                 int right = Math.min(left + size * 2 - 1, n - 1);
  62.                 merge(arr, left, mid, right);
  63.             }
  64.         }
  65.     }
  66.     public static void main(String[] args) {
  67.         int[] arr = {-2, 3, 0, 9, 6, 5, 4, 67, 2, 8, 1};
  68.         timSort(arr);
  69.         System.out.println("排序后的数组: ");
  70.         for (int value : arr) {
  71.             System.out.print(value + " ");
  72.         }
  73.     }
  74. }
复制代码
优缺点分析

优点


  • 稳固性:TimSort是稳固的排序算法,保持相称元素的原始次序。
  • 服从:对于多种数据分布,TimSort都能保持较好的性能,特殊是在部门有序的数据上。
  • 时间复杂度:最佳、匀称、最坏时间复杂度均为O(n log n)。
缺点


  • 空间复杂度:TimSort须要额外的暂时存储空间,空间复杂度为O(n)。
  • 实现复杂性:TimSort的实现比简单的排序算法复杂。
利用场景


  • 大数据集:TimSort恰当对大数据集举行排序,特殊是在数据大概部门有序的情况下。
  • 须要稳固性的场景:当排序须要保持相称元素的原始次序时,TimSort是一个好选择。
  • 多种数据分布:TimSort对数据分布不敏感,因此在不确定命据特性时是一个安全的选项。
结语

TimSort作为一种混淆排序算法,它连合了归并排序和插入排序的优点,提供了一种高效且稳固的排序计谋。固然它的实现相对复杂,但其精良的性能和稳固性使其成为很多编程语言和库中默认的排序算法

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表