图片转载自:https://blog.csdn.net/weixin_37818081/article/details/79202115
1.几个名词解释
1)增量(步长):待处理的序列中每个元素间的距离,可自行设置
增量设置的规则:
1.常用规则:increment = increment / 3 + 1(increment 的初始值为数组长度)
2.希尔规则:increment = increment / 2(increment 的初始值为数组长度)
2)基本有序:小的基本在前面,大的基本在后面,不大不小的基本在中间
2.排序思想
1)希尔排序是直接插入排序的改进,同属插入排序类,直接插入排序对基本有序的序列排序很高效,同时当元素个数比较少时,直接插入排序也很高效;针对这两个特性,希尔排序利用增量进行分组,对每个组进行排序,形成基本有序,同时分组后每组的元素个数也会变少
2)设置一个增量,将相距一个增量的元素组成若干个子序列,对每个子序列分别进行直接插入排序;然后按规则缩小增量,再次根据增量将整个序列分成若干子序列,并分别对子序列进行直接插入排序;不断重复上述操作,直到增量缩小到1,进行最后一次直接插入排序,则完成希尔排序。在上述过程中,整个序列会从无序——>基本有序——>有序
代码实现
void sortShell(vector<int>& nums, int length) { int increment = length; while (increment > 1) { increment = increment / 3 + 1; //增量为1时还会再排一次 for (int i = increment; i <= length - 1; ++i) { int j = i; while (j >= increment && nums[j] < nums[j - increment]) { swap(nums[j], nums[j - increment]); j = j - increment; } } } }
时间复杂度
最好情况O(n1.3),最坏情况O(n2),平均情况O(nlogn)~O(n2)
空间复杂度
O(1)
稳定性
由图可以看出是不稳定的。一次插入排序是稳定的,但在多次的子序列插入排序过程中,相同的元素可能在各自的插入排序中移动,并不能保证相同元素在排序前后的相对顺序,所以是不稳定的