希尔排序 Shell’s Sort
我们都知道直接插入排序对有序度高的列表排序效率是比较高的。而当列表为倒序时,最后一位元素的值是最小的,直接插入排序会进行 n-1 次比较才能找到正确的位置。这种情况下直接插入排序的效率是很低的
希尔排序是改进的直接插入排序,也称为缩小增量排序
希尔排序的基本思路:
把列表元素按下表的一定增量分组,对每组分别使用直接插入排序
这种做法成功的把大规模的有序度较低的数组转换成了小规模的有序度高的数组,因此直接插入排序的效率提高了
实现:
希尔排序的思路就是将大数组转化为小数组,分别插入排序后转化为有序度相对较高的数组,再利用插入排序
希尔排序的本质还是插入排序,但是通过将数组巧妙分割,恰好利用了插入排序对小数组和有序度高的数组效率高的特点
public static void shellSort1(int[] arr) {
int gap = arr.length / 2;
System.out.println(Arrays.toString(arr));
while (gap > 0) {
for (int i = gap; i < arr.length; i++) {
int j = i;
int temp = arr[j];
while (j - gap >= 0 && temp < arr[j - gap]) {
// 移动
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
// 打印
System.out.println(Arrays.toString(arr));
gap /= 2;
}
}
时间复杂度:
希尔排序的时间复杂度和增量序列(即 gap 的大小)有关,因此非常复杂
例如 {1, 2, 4, 8, … }这个序列的最坏时间复杂度为 O(n)
{1, 3, 7, 2 (k)-1, … } 的最坏时间复杂度为 O(n^{1.5})
{1, 5, 19, 41, 109, … } 的最坏时间复杂度为 O(n^{1.3})
空间复杂度:
由于只用到了 1 个临时变量,所以空间复杂度为O(1)
稳定性:
虽然插入排序是稳定的,但是希尔排序是多个插入排序交叉,所以可能破坏稳定性
相关章节
第一节 简述
第二节 稀疏数组 Sparse Array
第三节 队列 Queue
第四节 单链表 Single Linked List
第五节 双向链表 Double Linked List
第六节 单向环形链表 Circular Linked List
第七节 栈 Stack
第八节 递归 Recursion
第九节 时间复杂度 Time Complexity
第十节 排序算法 Sort Algorithm
第十一节 冒泡排序 Bubble Sort
第十二节 选择排序 Select Sort
第十三节 插入排序 Insertion Sort
第十四节 冒泡排序,选择排序和插入排序的总结
第十五节 希尔排序 Shell’s Sort
第十六节 快速排序 Quick Sort
第十七节 归并排序 Merge Sort