希尔排序
概述
希尔排序是对插入排序的改进,对要排序的序列定量分组,对每组使用插入排序算法。希尔排序的基本思想是将元素列在一个表中并对列分开进行插入排序。
以下面的例子进行演示,
# 待排序序列
[54, 26, 93, 17, 77, 31, 44, 55, 20]
# 第一轮 gap=4
54 77 20
26 31
93 44
17 55
对上面四组进行插入排序
20 54 77
26 31
44 93
17 55
合并得到新的序列
[20, 26, 44, 17, 54, 31, 93, 55, 77]
# 第二轮 gap=2
20 44 54 93 77
26 17 31 55
对上面两组进行排序
20 44 54 77 93
17 26 31 55
合并得到新的序列
[20, 17, 44, 26, 54, 31, 77, 55, 93]
# 第三轮 gap=1
20 17 44 26 54 31 77 55 93
对上面的序列进行插入排序
17 20 26 31 44 54 55 77 93
得到最终序列
[17, 20, 26, 31, 44, 54, 55, 77, 93]
算法实现
实现希尔排序首先需要明确的是一条分隔线,这条线就是gap,
实现序列的升序排列,
def shell_sort(alist):
n = len(alist)
# 初始化gap的值
gap = n // 2
while gap > 0:
for i in range(gap, n):
j = i
while j > 0:
if alist[j] < alist[j-gap]:
alist[j], alist[j-gap] = alist[j-gap], alist[j]
j -= gap
else:
break
gap = gap // 2
return alist
在实际情况下,gap的取值常常是互质的,因为gap以固定倍数缩减的时,在对部分有序的序列进行排序时,可能会出现很多没有用的比较。
算法时间复杂度及稳定性
复杂度 | 说明 |
---|---|
最坏时间复杂度 | O(n2),对应的是完全逆序数列的情况。 |
希尔排序的复杂度几乎是无法确切计算的,目前普遍认可的认为希尔排序的最优时间复杂度为O(n1.3)。
因为希尔排序把整个序列分成了多份,所以每一段中的插入排序是相互独立的,这也导致了希尔排序是不稳定的。