Timsort是一种复杂度高的排序算法,稳定并且效率很高,是python,java等默认使用的一种排序算法
Timsort从某种意义上来说是插入排序与归并排序的结合,
python中,
当一个列表的长度小于等于64时,则默认使用插入排序算法逻辑,对数据进行排序,因为在数据量较小的情况下,插入排序的效率很高,比选择,快排,希尔等都高。
当一个列表长度大于64时,就会结合归并和插入排序算法使用,当然,仅仅是使用他们的一部分而已。
Timsort的核心思想就是利用数组中的一部分有序数列,在Timsort中,数组中的每一段有序数列都被称之为‘run’分区,无论这个run分区是倒序或者是正序,Timsort都会将其调整为正序。
Timsort到底会建立多少run分区呢?这是通过minrun来限制的,通俗来讲,minrun就是run分区的限制条件,当数组长度大于64时,其范围为:[32,64],使得数组长度n/minrun的结果为2的整数次幂或者比2的整数次幂稍微小一点,而n/minrun的结果就是Timsort的初始run的个数。
依次寻找待排序序列中的run,当run的大小小于minrun的值的时候,就利用插入排序向后扩充run,直到与minrun的大小相同
给一段python简单实现的代码:
''''
timSort是python、Java等语言的内置排序函数。timSort将插入排序和归并排序结合,首先将
原始无须列表分割成一个个run,run是将原始无需序列按照对应关系分割而成,一般这里的run
制的是原始序列里面存在的有序序列。任何无序序列可以被分割成有序序列的集合。
说明:这里仅仅实现了timsort的雏形,没有考虑minrun。
'''
import time
def binary_search(the_array, item, start, end):#二分法插入排序
if start == end:
if the_array[start] > item:
return start
else:
return start + 1
if start > end:
return start
mid = round((start + end)/ 2)
if the_array[mid] < item:
return binary_search(the_array, item, mid + 1, end)
elif the_array[mid] > item:
return binary_search(the_array, item, start, mid - 1)
else:
return mid
def insertion_sort(the_array):
l = len(the_array)
for index in range(1, l):
value = the_array[index]
pos = binary_search(the_array, value, 0, index - 1)
the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:]
return the_array
def merge(left, right):#归并排序
if not left:
return right
if not right:
return left
if left[0] < right[0]:
return [left[0]] + merge(left[1:], right)
return [right[0]] + merge(left, right[1:])
def timSort(the_array):
runs, sorted_runs = [], []
length = len(the_array)
new_run = []
for i in range(1, length):#将序列分割成多个有序的run
if i == length - 1:
new_run.append(the_array[i])
runs.append(new_run)
break
if the_array[i] < the_array[i-1]:
if not new_run:
runs.append([the_array[i-1]])
new_run.append(the_array[i])
else:
runs.append(new_run)
new_run = []
else:
new_run.append(the_array[i])
for item in runs:
sorted_runs.append(insertion_sort(item))
sorted_array = []
for run in sorted_runs:
sorted_array = merge(sorted_array, run)
print(sorted_array)
arr = [45,2.1,3,67,21,90,20,13,45,23,12,34,56,78,90,0,1,2,3,1,2,9,7,8,4,6]
t0 = time.perf_counter()
timSort(arr)
t1 = time.perf_counter()
print('共%.5f秒' %(t1-t0))