1、插入排序有两种,直接插入排序和希尔排序
2、希尔排序核心思想
希尔排序本质也是一种插入排序,但是是根据简单插入排序进行优化有的一种更加高效的版本,别称是缩小增量排序。
希尔排序的核心思想是将排序数组按照增量进行分组,然后对分组的元素进行直接插入排序,循环缩小分组增量,最后当增量长度为1是排序结束。
3、举例:给不同身高的人进行排序
第一步:分组,找一个间隔分组,间隔取4。间隔通常是总长度的一半,奇数偶数均可。
如图所示:0,4,8一组;1,5一组,2,6一组;3,7一组。
第二步:对于每组元素,分别进行排序
第一组:0,4,8 已经排好序;
第二组:5,1
第三组:6,2
第四种:3,7
所有组拍完序后,此时:
第三步:继续设置间隔,这次的间隔是上次的一半,间隔取2
第一组:0,2,4,6,8
第二组:1,3,5,7
第四步:重复步骤二给每组排序:
第一组:2,0,6,4,8
第二组:3,7,1,5
全部排完序后:
第五步:再次设置间隔,间隔取上次的一半1
当间隔为1时,使用插入排序法,进行排序
最终结果:
方法总结:对每个分组进行插入排序
4、代码
对数组[83,29,30,5,99,34,12,66]使用希尔排序进行排序。
# 代码1
def shellsort(arr): #设置步长 gap = len(arr) while gap > 0: #遍历分组 for i in range(gap,len(arr)): #对当前分组的元素进行插入排序 for j in range(i,gap-1,-gap): if arr[j] < arr[j-gap]: arr[j],arr[j-gap]=arr[j-gap],arr[j] else: break print(arr) gap //= 2# 步长减半 return arr arr=[83,29,30,5,99,34,12,66] print("最终结果:",shellsort(arr))
结果:
#代码2:分成直接插入排序+希尔排序思想
def compare(arr,i,gap): #直接插入排序 j = i-gap while j>=0: if arr[j]>arr[j+gap]: arr[j+gap],arr[j]=arr[j],arr[j+gap] j-=gap else: break def shellSort(arr): gap=len(arr)//2 while gap>=1:#步长大于0的时候,都要做以下步骤 #1 分组 #2 对分组的元素进行直接插入排序 #3 缩小步长 for i in range(gap):#对每组都要进行直接插入排序 for j in range(i,len(arr),gap): compare(arr,j,gap) gap//=2 #一轮循环之后,才调整步长 return arr arr=[7,3,45,23,-1,34,88,9,4] print(shellSort(arr)) #结果[-1, 3, 4, 7, 9, 23, 34, 45, 88]
5、希尔排序的时间复杂度
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个素很少,速度很快;
当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。
所以希尔排序的时间复杂度比O(n^2)要好一些。