python实现希尔排序

假装没事ソ 提交于 2019-11-27 02:42:27

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)
最优复杂度:这个需要根据步长所决定
稳定性: 不稳定

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!