希尔排序主要是插入排序的一种变体。在插入排序中,我们每次只将元素向前移动一位。当一个元素离它排序后的位置很远时,我们需要移动很多次,从而导致整个算法的效率降低。希尔排序 的思想是允许不相邻的元素的交换。在希尔排序中,我们先使用较大的 h 值对数组进行 h 排序,之后不断减小 h 的值,直到它变为 1。如果每个第 h 个元素的所有子列表都已排序,则称数组是 h 排序的,其中h为子列的长度/间隙。
算法:
步骤 1 - 开始
步骤 2 - 初始化间隙大小的值,即 h 的值
步骤 3 - 将列表分成更小的子部分,每个子列表第一个元素和最后一个元素的间隔为h
步骤 4 - 使用插入排序对这些子列表进行排序
步骤 5 - 缩小h,并重复步骤 2 直到列表完全排序(此时h应为1)
步骤 6 – 停止
让我们来看希尔排序的Python实现以便更好的理解上面的步骤:
def shellSort(arr, n):
gap=n//2
while gap>0:
j=gap
# Check the array in from left to right
# Till the last possible index of j
while j<n:
i=j-gap # This will keep help in maintain gap value
while i>=0:
# If value on right side is already greater than left side value
# We don't do swap else we swap
if arr[i+gap]>arr[i]:
break
else:
arr[i+gap],arr[i]=arr[i],arr[i+gap]
i=i-gap # To check left side also
# If the element present is greater than current element
j+=1
gap=gap//2
arr2 = [12, 34, 54, 2, 3]
print("input array:",arr2)
shellSort(arr2,len(arr2))
print("sorted array",arr2)
输出:
排序前的数组: 12 34 54 2 3
排序后的数组: 2 3 12 34 54
时间复杂度:
最坏时间复杂度
上述希尔排序实现的最坏时间复杂度仍然为O(n^2 )。在上述实现中,每次迭代将间隙减少一半。还有许多其他方法可以减少间隙,从而提高时间复杂度,感兴趣的同学可以自行拓展了解。
最佳时间复杂度
当给定的数组列表已经排序时,每个区间的比较总数等于给定数组的大小。所以最好的情况复杂度是 O(n log(n))
平均时间复杂度: O(n log(n)),希尔排序的时间复杂度主要取决于区间大小的选择
空间复杂度:O(1),希尔排序不需要额外的辅助空间
希尔排序的应用:
1.替换不高效的插入排序
2. 堆栈的开销使用希尔排序。
3. 当递归超过特定限制时,我们使用希尔排序。
4. 适用于大中型数据集。
其他语言代码实现下载链接:
(包含各种语言:C、Python、Java、C++、C#等)
免费资源下载:Shell Sort