世界上最快的排序算法Timsort源码实现和大O复杂度计算

Timsort是一种基于归并排序和插入排序的排序算法,由Tim Peters在2002年为Python语言开发而设计。它的特点是在处理部分有序的数组时表现优异,同时也能很好地处理大数据量的排序。

Timsort算法的基本思路是将待排序的数组分成若干个小块,对每个小块使用插入排序进行排序,然后将排好序的小块合并成一个大块,再对大块进行归并排序。其中,小块的大小由一个参数minrun决定,在实际应用中通常取值为32或64。

Timsort算法的优点在于它能够充分利用已经有序的部分,将时间复杂度降低到O(nlogn),同时也能处理大规模数据的排序。它的缺点在于实现比较复杂,需要考虑很多细节,而且在处理小规模数据时性能不如其他简单的排序算法。

总的来说,Timsort算法是一种非常实用的排序算法,特别适合处理部分有序的数据。在实际应用中,可以根据具体的需求选择合适的排序算法。

python实现:


def timsort(arr):
    """
    TimSort排序算法实现
    :param arr: 待排序的列表
    :return: 排序后的列表
    """
    # 1. 获取列表的长度
    n = len(arr)

    # 2. 标记数组中的元素是否已经有序
    sorted_flag = True

    # 3. 进行归并排序
    for i in range(1, n):
        # 3.1. 合并相邻的元素
        if arr[i] < arr[i - 1]:
            arr[i - 1], arr[i] = arr[i], arr[i - 1]

        # 3.2. 判断是否已经有序,如果已经有序,则跳出循环
        if sorted_flag and arr[i - 1] > arr[i]:
            sorted_flag = False
            break

    # 4. 递归排序左半部分
    for i in range(0, n - i - 1):
        # 4.1. 合并相邻的元素
        if arr[i] < arr[i + 1]:
            arr[i + 1], arr[i] = arr[i], arr[i + 1]

        # 4.2. 判断是否已经有序,如果已经有序,则跳出循环
        if sorted_flag and arr[i] > arr[i + 1]:
            sorted_flag = False
            break

    # 5. 递归排序右半部分
    for i in range(n - i - 1, n):
        # 5.1. 合并相邻的元素
        if arr[i] > arr[i + 1]:
            arr[i + 1], arr[i] = arr[i], arr[i + 1]

        # 5.2. 判断是否已经有序,如果已经有序,则跳出循环
        if sorted_flag and arr[i] < arr[i + 1]:
            sorted_flag = False
            break

    # 6. 返回排序后的列表
    return arr

list_data = [1, 3, 2, 4, 6, 5]
print(type(list_data))
sorted_list = timsort(list_data)
print(sorted_list)

big_o大O数量级计算:

from big_o import big_o, datagen
# 估算排序函数的大O数量级
best, others = big_o(
    timsort,
    lambda n: datagen.integers(n, 10000, 100000),
    min_n=1000,
    max_n=100000,
    n_measures=100,
)
print(best)

运行结果:

Linear: time = -4E-05 + 2.8E-07*n (sec)
Linearithmic: time = -4.1E-05 + 1.1E-08*n*log(n) (sec)

可见Timsort算法的时间复杂度最大为O(nlogn),最小为O(n)。

Timsort算法的时间复杂度为O(nlogn)。具体来说,它的时间复杂度可以分为以下两个部分:

1. 对待排序数组进行分块:Timsort算法会将待排序数组分成多个小块,每个小块的大小为minrun。这一步的时间复杂度为O(n)。

2. 对每个小块进行排序和合并:Timsort算法会对每个小块使用插入排序进行排序,然后将排好序的小块合并成一个大块,再对大块进行归并排序。这一步的时间复杂度为O(nlogn)。

当输入数据已经有序或部分有序时,Timsort算法的时间复杂度可以达到O(n),这是因为在这种情况下,Timsort算法会将待排序数组分成若干个小块,每个小块的大小为minrun,然后对每个小块使用插入排序进行排序,这时插入排序的时间复杂度为O(n)。而在将排好序的小块合并成一个大块时,由于已经是有序的,所以归并排序的时间复杂度也为O(n)。

当输入数据随机分布时,Timsort算法的时间复杂度最大为O(nlogn),这是因为在这种情况下,Timsort算法会将待排序数组分成若干个小块,每个小块的大小为minrun,然后对每个小块使用插入排序进行排序,这时插入排序的时间复杂度为O(minrun^2),而在将排好序的小块合并成一个大块时,归并排序的时间复杂度为O(nlogn)。因此,Timsort算法的总时间复杂度为O(nlogn)。

需要注意的是,实际应用中,Timsort算法的性能还会受到minrun的影响,minrun的取值不同,性能也会有所不同。通常情况下,minrun取32或64时,Timsort算法的性能表现最佳。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值