1.什么是希尔排序:
希尔排序(Shell’s Sort)是插入排序的一种,又称“缩小增量(间隔)排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本它与插入排序的不同之处在于,它会优先比较距离较远的元素,该方法因D.L.Shell于1959年提出而得名。

2.算法思想:
希尔排序的整体思想是将固定间隔的几个元素之间排序,然后再缩小这个间隔。这样到最后数列就成为了基本有序数列,而前面我们讲过插入排序对基本有序数列排序效果较好。
(1)计算一个增量(间隔)值
(2)对元素进行增量元素进行比较,比如增量值为7,那么就对0,7,14,21…个元素进行插入排序
(3)然后对1,8,15…进行排序,依次递增进行排序
(4)所有元素排序完后,缩小增量比如为3,然后又重复上述第2,3步
(5)最后缩小增量至1时,数列已经基本有序,最后一遍普通插入即可

3.python3代码实现

# -*- coding: utf-8 -*-
"""
Created on Wed Jul 10 22:24:52 2019

@author: ZQQ
"""

def shellSort(input_list):
    n = len(input_list) # 计算待排序序列的长度
    if n <= 1:
        return input_list
    gap = n // 2 # 取增量
    while gap > 0:
        # 从增量开始遍历比较
        for i in range(gap,n):
            j = i 
            current = input_list[i]
            # 当前元素与同列的前面的每个元素比较,如果比前面的小则互换
            while j - gap >= 0 and current < input_list[j - gap]:
                input_list[j] = input_list[j - gap]
                j -= gap
            input_list[j] = current
        # 缩小增量
        gap //= 2
    return input_list
            
input_list = [2,4,5,1,3]
print('排序前:',input_list)
sorted_list = shellSort(input_list)
print('排序后:',sorted_list)
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 10 22:44:56 2019

@author: ZQQ
"""

# -*-coding:utf-8 -*-
def shellSort(input_list):
    length = len(input_list)
    if length <= 1:
        return input_list
    sorted_list = input_list
    gap = length // 2
    while gap > 0:
        for i in range(gap, length):
            j = i - gap
            temp = sorted_list[i]
            while j >= 0 and temp < sorted_list[j]:
                sorted_list[j+gap] = sorted_list[j]
                j -= gap
            sorted_list[j+gap] = temp
        gap //= 2
    return sorted_list 
 
if __name__ == '__main__':
    input_list = [50, 123, 543, 187, 49, 30, 0, 2, 11, 100]
    print('排序前:', input_list)
    sorted_list = shellSort(input_list)
    print('排序后:', sorted_list)

4.算法分析:

(1)比较性:排序时元素之间需要比较,所以为比较排序
(2)稳定性:因为希尔排序是间隔的插入,所以存在相同元素相对顺序被打乱,所以是不稳定排序
(3)时间复杂度: 最坏时间复杂度O(n^2) ;平均复杂度为O(nlogn)
(4)空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)

步长的选择是希尔排序的重要部分。只要最终步长为1任何步长序列都可以工作。

5.希尔VS直接插入
直接插入排序是稳定的;而希尔排序是不稳定的。
直接插入排序更适合于原始记录基本有序的集合
希尔排序的比较次数和移动次数都要比直接插入排序少,当N越大时,效果越明显。
在希尔排序中,增量序列gap的取法必须满足:最后一个步长必须是 1 。
直接插入排序也适用于链式存储结构;希尔排序不适用于链式结构。