希尔排序的原理是按照一定的间距 d 将数组中的元素分组,进行分别插入排序,再逐步缩小 d 的值,反复进行插入排序,最后按照正确顺序输出。
假设一个数组为 array=[2,5,3,9,1,4,7,0],共8个元素
采用二分法确定每次排序的间距 d ,则 d =4,2,1
当 d=4 时,原数组分为(2,1)(5,4)(3,7)(9,0)四组,按照判断大小并交换顺序为
(1,2)(4,5)(3,7)(0,9),之后的数组
array=[1,4,3,0,2,7,5,9]
当 d=2 时,上述数组分为(1,3,2,5)(4,0,7,9)两组,对这两组进行插入排序,结果分别为(1,2,3,5)(0,4,7,9),之后的数组
array=[1,0,2,4,3,7,5,9]
当 d=1 时,重新对上述整个数组进行插入排序,之后输出正确结果。
===============================================
程序的难点在于每一次切换 d 时的衔接,经过艰苦学习多方参考,代码如下:
import numpy as npdef shell_sort(array):L=len(array)d=int(L/2)while(d):for i in range(d,L):for j in range(i,0,-1*d):a=j-dwhile(a>=0):if array[j-d]>array[j]:array[j-d],array[j]=array[j],array[j-d]else:breakd=int(d/2)return arrayarray = np.random.randint(0, 11, 6)
print(array)
array_sort=shell_sort(array)
print(array_sort)
========================================
- 难点在于确定变量 i 的迭代范围,这里选择 range(d,L),就不用考虑如何将两个数组分离开来比较,这是当初一直没有想通的地方
- 加入 a = j - d 这一行,是因为我担心一种情况,假设 j= 1,d =4 那么在接下来的 array [ j - d ] 会出现问题
- 当 L 为奇数时,使用二分法不会影响结果,大可放心~
- 有很多人提出不使用简单的二分法来确定 d 的值,那么可以直接在 d = int ( d / 2 ) 处修改,加入一个变量 k ,把 d 确定成关于 k 的函数就可以了
- 学会了python中的变量交换方式
- 希尔排序是一种不稳定排序,可能会把相同元素分在不同的小组中,这样就打乱了相同元素的顺序