原文地址:http://brianleelxt.top/2018/08/05/shellsort/
《Algorithm》(Sedgewick)笔记:希尔排序
原理
- 改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序
- 希尔排序的思想是使数组中任意间隔为h的元素都是有序的,这样的数组被称为h有序数组。换句话说,一个h有序数组就是h个互相独立的有序数组编织在一起组成的一个数组
复杂度
时间复杂度
不超过O(n2)O(n^2)O(n2) ,当nnn 较大时,比较和移动次数约在n1.25n^{1.25}n1.25 到1.6n1.251.6n^{1.25}1.6n1.25
空间复杂度
O(1)O(1)O(1)
图示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e2uvYxCi-1592197230999)(http://p5mjtapdi.bkt.clouddn.com/img/sort/shellsort.PNG “希尔排序”)]
代码
public static void sort(Comparable[] a) {
int N = a.length;
int h = 1;
while (h < N / 3)
h = 3 * h + 1;
while (h >= 1) {
//分别进行插入排序
for (int i = h; i < N; i++) {
for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
exch(a, j, j - h);
}
h = h / 3;
}
}
上述代码使用了序列12(3k−1)\frac{1}{2}(3^k-1)21(3k−1) ,从N/3N/3N/3 开始递减至111
序列计算:
hk+1=3×hk+1(h1=1)h_{k+1}=3\times h_k+1 (h_1=1)hk+1=3×hk+1(h1=1)
hk+1+12=3(hk+12)h_{k+1}+\frac{1}{2} = 3(h_k+\frac{1}{2})hk+1+21=3(hk+21)
∴hk+12=32×3k−1\therefore h_k+\frac{1}{2}= \frac{3}{2}\times 3^{k-1}∴hk+21=23×3k−1
∴hk=12(3k−1)\therefore h_k=\frac{1}{2}(3^k-1)∴hk=21(3k−1)
特点
- 希尔排序更高效的原因是它权衡了子数组的规模和有效性
- 时间复杂度取决于N与增量序列
- 如何选择最佳增量序列,目前尚未解决,但最后一个增量值必须为1,且避免增量序列中的值(尤其是相邻的值)有公因子
源码
https://github.com/XutongLi/Algorithm-Learn/blob/master/src/S2_Sorting/S2_1_6_ShellSort/ShellSort.java
本文详细介绍了希尔排序的工作原理及其实现过程。希尔排序通过改进插入排序,实现了对数组中不相邻元素的有效排序,提高了排序效率。文章还提供了具体的时间复杂度分析及代码示例。
263

被折叠的 条评论
为什么被折叠?



