python实现希尔排序
希尔排序:
实现分析:
实际上希尔排序就是对插入排序的一种改进而已,
希尔排序是将整个列表当成一个无序序列,并将其分成多个无序序列来进行插入排序,而实现分成多个序列就是需要一个gap步长来实现,对于普通的插入排序gap就是等于1。
我们还是以 __[54,26,93,17,77,31,44,55,20]__为例子。为了分析,我们假设gap先等于2,
图一是我们未划分之前的列表,图二是根据gap划分而来的两个列表,我们需要对每一个列表进行插入排序,排序玩以后得到如下的图
此时步长为2时已经排序完成,现在我们就需要减小步长为1再次进行排序,这时就与普通的插入排序一样了,笔者就不再多说,对于插入排序,可以参考链接: 普通的插入排序实现.
(1)首先我们先把插入排序比较的框架写出来
while i>0:
if alist[i]<alist[i-1]:
alist[i],alist[i-1]=alist[i-1],alist[i]
i-=1
else:
break
但是对于希尔排序来说比较的不再是前一个元素,而是以步长来比较的元素,所以这里的1需要改成gap。
(2)对于(1)来说我们仅仅实现了第一步,对于一次进行的排序,而对于一整个序列来说我们需要比较多次,所以我们需要用到一个for循环for j in range(gap,n ): i=j
这里为什么从gap开始记录,是因为我们是从后往前进行比较的,就拿下面的图为例子,第一个序列中Gap与54比较,第二个gap+1与26比较以此类推,换一种理解方式就是因为我们是从后往前比较,且步长为gap,所以我们要使得alist[i-gap]的下标必须大于或等于0才行。
(3)对于步长我们需要进行按照某种规则去递减,这里我们以折半进行递减,当gap步长为1的时候,就是整个序列排序完成的时候。
while gap>=1:
gap//=2
所以代码里面有这一步骤
代码实现:
def shell_sort(alist):
"""希尔排序"""
n=len(alist)
gap=n//2
#i=1
#gap变换到1的时候,插入算法执行的次数
while gap>=1:
#插入算法,与普通插入算法的区别就是gap步长
for j in range(gap,n ):
i=j
while i>0:
if alist[i]<alist[i-gap]:
alist[i],alist[i-gap]=alist[i-gap],alist[i]
i-=gap
else:
break
#缩小步长
gap//=2
if __name__=="__main__":
a=[54,26,93,17,77,31,44,55,20]
print("排序之前的数为:")
print(a)
print("排序之后的数为:")
shell_sort(a)
print(a)
时间复杂度:
最坏复杂度:O(N*N)
最优复杂度:这个需要根据步长所决定
稳定性: 不稳定
来源:https://blog.csdn.net/qq_45353823/article/details/99289446