前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >深入了解 Python 中标准排序算法 Timsort

深入了解 Python 中标准排序算法 Timsort

作者头像
叶庭云
发布于 2024-05-25 00:10:44
发布于 2024-05-25 00:10:44
1810
举报
文章被收录于专栏:Python进阶之路Python进阶之路

Timsort:一个非常快速的、时间复杂度为

O(n log n)

、稳健(即不改变等值元素间的相对顺序)的排序算法,在处理真实世界数据(经常出现部分有序情况)时表现出色,而不只是为学术研究。

为什么 Python 中的标准排序算法使用 Timsort?

Python 中的标准排序算法之所以使用 Timsort,是因为这种排序算法非常适合处理实际应用中常见的各种数据。Timsort 是由 Tim Peters 在 2002 年为 Python 设计的一种排序算法,现已被广泛应用于 Python 的 sorted() 函数和列表的 .sort() 方法中。Timsort 基于归并排序(Merge Sort)和插入排序(Insertion Sort)的优点,针对实际应用中的数据特点进行了优化。以下是使用 Timsort 的几个主要原因:

  1. 稳健性:Timsort 是一种稳健的排序算法,能够在排序后保持等值元素间的相对顺序不变。这对于复杂数据结构或需要维护元素间相对顺序的应用场景非常重要。
  2. 适应性:Timsort 能够识别输入数据中已经有序或部分有序的片段(称为 “run”),并利用这些信息来优化排序过程。这使得它在处理部分有序的数据时表现出色,可以显著减少所需的比较和移动操作。
  3. 高效性:对于不同类型和大小的数据集,Timsort 都能提供接近最优的性能。它将数据分割成小块进行插入排序,然后再通过归并排序将它们合并起来,有效地结合了这两种算法各自的优势。TimSort 的平均时间复杂度为
O(n log n)

,最佳情况下为

O(n)

,最差情况下也为

O(n log n)

  1. 空间效率:尽管 Timsort 需要额外的空间来进行归并操作,但它通过动态调整运行策略来优化空间使用,使得其空间复杂度通常表现得比纯归并排序更优。
  2. 实际性能:实际测试和使用表明,Timsort 在多种编程语言和环境中都展现出了优异的性能。Timsort 是 Python 的标准排序算法,也被广泛应用于 Java SE 7 中对非原始类型数组进行排序。此外,它在 Android 平台、GNU Octave、V8 和 Swift 等多个平台上也有使用。Timsort 的算法设计还启发了 Rust 中使用的排序算法。

总之,Timsort 之所以成为 Python 中标准排序算法,是因为它综合考虑了稳健性、适应性、高效性和空间效率等多方面因素,并且针对实际应用中频繁遇到的数据特点(有序或部分有序)进行了专门优化。这使得 Timsort 成为处理各种复杂数据场景时一个非常可靠和高效的选择。

Timsort 的关键原理和具体实现

Timsort 的关键在于它利用了实际数据中经常出现的有序序列(称为 “run”),并通过智能地将这些 run 合并,达到较高的排序效率。算法主要包含以下几个关键原理:

  1. 寻找自然有序序列(Run):Timsort 首先会遍历数据,寻找或创建较小的有序片段,这些片段称为 run。如果数据自然倾向于部分有序,Timsort 将利用这一点来减少工作量。
  2. 最小运行长度(Minrun)选择:算法会根据数组大小动态选择一个最小运行长度(minrun),以平衡运行时间和所需的合并操作数。这个值通常在 32 到 64 之间,目的是确保运行的大小既不会太小也不会太大。
  3. 构建和维护运行堆栈:Timsort 维护一个运行堆栈,其中每个元素代表一个已排序的 run。它会尝试保持堆栈大小尽可能小,并通过合并操作维护某些特定性质(例如,确保较短的 run 尽可能在堆栈顶部)。
  4. 智能合并策略:当堆栈中的 run 数量达到一个阈值时,或者所有输入都已转换为 run 时,Timsort 开始合并这些 run。它使用了一套复杂的规则来决定哪两个相邻的 run 应该被合并,以及何时进行合并。
  5. 二分插入排序:在较短的 run 或在合并过程中插入单个元素时,Timsort 会使用二分查找来减少比较次数,并因其在处理小数组时的高效性而采用插入排序。

虽然详细代码实现相对复杂,但以下是 Timsort 实现中一些关键步骤的简化概述:

  1. 初始化:选择一个适当的 minrun 长度。
  2. 遍历数组:寻找或创建 run,并根据需要通过插入排序扩展这些 run 至少到 minrun 长度。
  3. 管理运行堆栈
    • 将新创建或发现的 run 推送到堆栈上。
    • 检查并遵循特定规则(如 Galloping 模式)来确定是否需要执行合并操作,并执行合并以保持堆栈平衡。
  4. 重复上述步骤,直到整个数组被分割成 run 并且所有 run 被合并成一个单一有序列表为止。

以下是 Timsort 排序算法的一些独特优势

  1. 自适应性:Timsort 能够根据数组的实际情况调整其策略,针对部分有序的数据集表现出色。它利用现有的顺序(自然 “run”),这使得它在处理部分有序数组时非常高效。
  2. 稳健性:Timsort 是一种稳健的排序算法,能够在排序后保持等值元素间的相对顺序不变。这对于某些应用,如数据库排序或多关键字排序,至关重要。
  3. 时间复杂度:对于随机数据,Timsort 的时间复杂度为
O(n log n)

,这与其他有效排序算法(如快速排序、归并排序)相当。然而,在最佳情况下,即当输入数组已经部分有序时,它可以达到接近

O(n)

的性能。

  1. 空间效率:尽管 Timsort 需要额外的空间来进行归并操作,但它通过动态调整运行大小和采用临时存储空间的策略来优化空间使用,使得其空间复杂度相对较低。
  2. 可扩展性:Timsort 很好地适应了不同大小和类型的数据集。它通过动态调整运行策略,可以有效地处理小数组到大型数据集。
  3. 最小运行查找:Timsort 通过寻找自然运行并在必要时通过执行最小量插入排序来创建最小长度运行,从而提高了其对实际数据集合中常见模式的适应性。
  4. 智能归并操作:Timsort 使用了多种归并策略,包括直接合并相邻运行和使用二分查找技术选择合适的归并策略。这些策略帮助减少不必要的比较和内存移动操作。
  5. 实践证明其有效性:由于其在 Python 和 Java 等广泛使用的语言中作为默认排序算法,Timsort 已经在各种真实场景中得到了广泛测试和验证,证明其高效、可靠。

总之,Timsort 的独特之处在于其将插入排序与归并排序结合起来,并针对实际使用场景进行了多项优化。这使得 Timsort 不仅在理论上高效,在处理现实世界数据时也显示出极高的性能和稳定性。

📚️ 相关链接:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
除了冒泡排序,你知道Python内建的排序算法吗?
Timsort 是一种对真实数据非常有效的排序算法。Tim Peters 在 2001 年为 Python 编程语言创造了 Timsort。Timsort 首先分析它要排序的列表,然后基于该分析选择合理方案。
机器之心
2018/12/17
5850
数据结构与算法系列之常用算法:排序算法
根据数组的元素个数、nearly sorted(近单调性:单调升序和单调降序)和元素类型等来选在具体排序算法。例如对整数排序:
尜尜人物
2020/01/15
5130
数据结构与算法系列之常用算法:排序算法
2021-01-14:timsort是什么,如何用代码实现?
timsort是一种混合、稳定高效的排序算法,源自合并排序和插入排序,旨在很好地处理多种真实数据。它由Tim Peters于2002年实施使用在Python编程语言中。该算法查找已经排序的数据的子序列,并使用该知识更有效地对其余部分进行排序。这是通过将已识别的子序列(称为运行)与现有运行合并直到满足某些条件来完成的。从版本2.3开始,Timsort一直是Python的标准排序算法。如今,Timsort 已是是 Python、 Java、 Android平台 和 GNU Octave 的默认排序算法。
福大大架构师每日一题
2021/01/14
1.1K0
Tim Peters关于Timsort排序算法的说明
This describes an adaptive, stable, natural mergesort, modestly called
yuezht
2023/09/24
4491
玄学优化一个稳定排序算法
前一阵子(还挺前的)正好在忙数据结构的课程设计,大体是要求做一个航班管理系统。程序主体就是简单堆几个高效数据结构,再糊上一个RESTful API,没什么好谈的。不过在优化其中的排序算法时倒是学到了挺多。虽然说本质还是缝合若干优秀算法,但刚好最近也很久没更新博客了,所以干脆写一篇博客简述当时的思路吧。优化思路本身都是拾人牙慧,有错漏还请指出。
KAAAsS
2022/01/14
5010
玄学优化一个稳定排序算法
图解排序算法(四)之归并排序
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
后端码匠
2021/05/10
3780
图解排序算法(四)之归并排序
详解排序算法(Python实现)
与许多其他高级编程语言一样,Python语言提供了使用sorted()函数对数据进行开箱即用的功能。示例:
宇宙之一粟
2020/10/26
5360
【面试题精讲】Java Stream排序的实现方式
在Java中,使用Stream进行排序可以通过sorted()方法来实现。sorted()方法用于对Stream中的元素进行排序操作。具体实现如下:
程序员朱永胜
2023/09/04
1.4K0
温故而知新:对排序算法的新认识
首次认识排序算法还是在大二的《数据结构》课程上听老师介绍的。那时候颇不理解,不仅不理解这些排序算法,更不理解为什么机械学院要开设《数据结构》这门课程。后来在大四以及此后的硕士项目过程中,我真有用到排序算法,不过当时图方便,而且数据量不大,我使用的冒泡排序(编码简单)。之后与排序算法结缘,是准备秋招。为了考试,为了项目,为了秋招,回顾这几次与排序算法的近距离接触,我并没有真正理解各类排序算法的原理。
用户6557940
2022/07/24
2530
温故而知新:对排序算法的新认识
Arrays.Sort()中的那些排序算法
Arrays.Sort方法所用的排序算法主要涉及以下三种:双轴快速排序(DualPivotQuicksort)、归并排序(MergeSort)、TimSort,也同时包含了一些非基于比较的排序算法:例如计数排序。其具体最终使用哪一种排序算法通常根据类型以及输入长度来动态抉择。
Rekent
2021/03/05
8750
Arrays.Sort()中的那些排序算法
插入排序算法,就这么简单
什么是算法?算法是某种集合,是简单指令的集合,是被指定的简单指令集合。确定该算法重要的指标:
Java_老男孩
2019/12/24
3790
插入排序算法,就这么简单
八大排序算法的 Python 实现
本文用Python实现了插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
胡八万
2022/05/16
1840
八大排序算法的 Python 实现
七大经典、常用排序算法的原理、Java 实现以及算法分析
大家好,我是多选参数的程序锅,一个正在 neng 操作系统、学数据结构和算法以及 Java 的硬核菜鸡。数据结构和算法是我准备新开的坑,主要是因为自己在这块确实很弱,需要大补(残废了一般)。这个坑以排序为开端,介绍了 7 种最经典、最常用的排序算法,分别是:冒泡排序、插入排序、选择排序、归并排序、快速排序、桶排序、计数排序、基数排序。对应的时间复杂度如下所示:
syy
2020/06/23
7600
面试中可能被问到的常用排序算法
排序算法是一种比较简单的算法,从我们一开始接触计算机编程开始接触的可能就是排序或者搜索一类的算法,但是因为排序在其他的一些算法中应用较多,所以为了提高性能已经研究了多种排序算法。目前区别排序算法主要还是以时间复杂度,空间复杂度,稳定性等来排序,接下来我们分别分析。
本人秃顶程序员
2019/05/12
7250
面试中可能被问到的常用排序算法
排序算法python实现
编写软件最基础莫过于算法了。今天在翻阅python的学习资料时,看到了别人用python实现的8大排序算法。很惭愧作为一个9年工作经验的程序员,现在还记得的排序只剩下冒泡排序、快速排序等寥寥几个了。于是花了数个小时将这些排序算法又仔细揣度了一番,同时再一次感叹python语言的精练。 八大排序算法 插入排序 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序。时间复杂度最好的情况为O(n),最坏的情况是O(n^2) 。是稳定的排序方法
jeremyxu
2018/05/10
8030
读 Java TimSort算法 源码 笔记
本来准备看Java容器源码的。但是看到一开始发现Arrays这个类我不是很熟,就顺便把Arrays这个类给看了。Arrays类没有什么架构与难点,但Arrays涉及到的两个排序算法似乎很有意思。那顺便把TimSort算法和双指针快速排序也研究一下吧。
yuxiaofei93
2018/09/11
1.4K0
【数据结构与算法】十大经典排序算法深度解析:冒泡排序、选择排序、插入排序、归并排序、快速排序、希尔排序、堆排序、计数排序、桶排序、基数排序
这个序列是逐渐减小的,gap的值较大时,数据可以更快的前后变动,但不容易"基本有序";gap较小时数据前后变动较慢,但更接近"基本有序"。 通常可以选取gap = n/3, gap = gap/3, ...,直到gap= 1。
倔强的石头_
2024/12/06
2K0
【数据结构与算法】十大经典排序算法深度解析:冒泡排序、选择排序、插入排序、归并排序、快速排序、希尔排序、堆排序、计数排序、桶排序、基数排序
【算法入门】用Python手写五大经典排序算法,看完这篇终于懂了!
算法作为程序员的必修课,是每位程序员必须掌握的基础。作为Python忠实爱好者,本篇将通过Python来手撕5大经典排序算法,结合例图剖析内部实现逻辑,对比每种算法各自的优缺点和应用点。相信我,耐心看完绝对有收获。
黄博的机器学习圈子
2020/05/26
1.5K0
【算法入门】用Python手写五大经典排序算法,看完这篇终于懂了!
极客算法训练笔记(七),十大经典排序之归并排序,全网最详
冒泡,选择和插入排序,它们的时间复杂度都是O(n2),比较高,适合小规模数据的排序;希尔排序和快速排序都不稳定,这篇我们来说说稳定的归并排序。归并排序在数据量大且数据递增或递减连续性好的情况下,效率比较高,且是O(nlogn)复杂度下唯一一个稳定的排序,致命缺点就是空间复杂度O(n)比较高。
阿甘的码路
2020/12/15
4850
极客算法训练笔记(七),十大经典排序之归并排序,全网最详
深入理解Spark 2.1 Core (十二):TimSort 的原理与源码分析
在博文《深入理解Spark 2.1 Core (十):Shuffle Map 端的原理与源码分析 》中我们提到了:
小爷毛毛_卓寿杰
2019/02/13
1.1K0
推荐阅读
相关推荐
除了冒泡排序,你知道Python内建的排序算法吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档