希尔排序算法/排序算法总结

希尔排序

希尔排序是插入排序的一种。也叫做缩小增量排序。是直接插入排序的更高效的改进版。希尔排序是非稳定排序算法。

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

思路:不要认为序列是一个有机的整体,而是有很多个无序的序列组成的,希尔排序就是分段分组的插入排序

1.取间隔为四,把他们分为几个无序序列

然后对每个无序序列进行插入排序

对第一个无序序列排序如下:

对第二个无序序列排序

对第三个无序序列排序

对第四个无序序列排序

第一趟排序完成之后结果如下:

2.取间隔为四二,把他们分为两个无序序列

把第一个无序序列按照插入算法排序后结果如下:

把第二个无序序列按照插入算法排序后结果如下:

第二趟排序完成之后结果如下:

3.取间隔为一,即他们就是一个无序的序列

如下图:

然后对这个无序序列进行插入算法排序

写算法的时候i的值为如下图

i从一个序列的中间位置开始取值,然后每次加一,加一的同时在自己这一行进行插入排序,

整体考虑的话如下:

第一次i=gap(没有拿20来比较大小):

第二次i=gap+1:

第三次i=gap+2:

    比较完成之后进行交换

第四次:

第五次:

i=gap+4即为最后一个元素,然后在这里进行插入排序

希尔排序算法的内层是插入排序算法。

#希尔排序每个无序部分还是按照插入排序写的
def shell_sort(alist):
    """希尔排序"""
    n=len(alist)    #n=9
    gap=n//2        #间隔取队列长度的一半,下一次再取,  gap=4

    #这个while循环控制的是gap变化到1的过程中执行的次数
    while gap>=1:    #步长需要取到1,因为2个子序列有序不意味着两个子序列合到一起之后也是有序的

        #希尔算法,与普通插入算法的区别就是gap步长。
        for j in range(gap,n):      #外层循环控制的是所有子序列的所有元素
            i=j
            #内层循环控制的是子序列执行的特定算法的比较和交换
            while i >= gap:            #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 #缩短gap步长
if __name__ == '__main__':
    alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
    shell_sort(alist)
    print(alist)
#结果为[17, 20, 26, 31, 44, 54, 55, 77, 93]

希尔排序的不稳定性体现在如下:

把他们分成两组,两组里面有两个77

执行第二次的时候结果为:

很显然不稳定,已经破坏了排序的有序性

猜你喜欢

转载自blog.csdn.net/qq_39112101/article/details/88599789