希尔排序是插入排序的一种改进版本,Donald Shell在1959年提出而得名。
希尔排序的实现思路:设定一个缩小增量的规则,以某个增量对数组进行分组,对每个分组进行直接插入排序,然后缩小增量再次分组依次类推,直到增量缩小到1,程序结束。
希尔排序的时间复杂度与增量序列的选取有关。关键词比较次数、记录移动次数和增量序列选择之间的关系,至今没有一个统一的公式可以归纳。在中小规模的排序中,希尔排序占优,在大规模数据量的排序中快排占优。在实际场景中根据测试数据结果选择使用哪种排序。
稳定性:不稳定,相同的元素可能会颠倒位置。
空间复杂度:O(1)
Java版的一种实现如下:
public void sort(T[] arr) {
if (arr == null || arr.length == 1) {
return;
}
int len = arr.length;
List<Integer> stepArr = new ArrayList<>();
int left = 1;
while (left < len / 3) {
stepArr.add(left);
left += 2;
}
for (int i = stepArr.size() - 1; i >= 0; i--) {
for (int j = 0; j < stepArr.get(i); j++) {
sort1(arr, j, stepArr.get(i));
}
}
}
private void sort1(T[] arr, int left, int step) {
//插入排序
int len = arr.length;
for (int i = left + step; i < len; i += step) {
for (int j = i; j > left; j -= step) {
if (arr[j].compareTo(arr[j - step]) < 0) {
swap(arr, j, j - step);
} else {
break;
}
}
}
}