希尔排序 ShellSort
1.基本描述
-
shellsort 是插入排序的一种。所以是直接插入排序算法的改进!。因 DL.Shell于1959年提出而得名
-
本质是 分组插入排序,对于n个待排序数列,娶一个小于n 的证书gap。将待排序元素分为若干个组子序列,所有距离为gap的记录放在同一个组中,然后,对各组内的元素进行 直接插入排序。
建议自己代码分块观察。其实是直接插入排序外套双循环,外循环为gap步长,内循环是由于gap取长不一样,分组的数量不同,要对每一组都做直接插入排序
稳定性 不稳定
时间复杂度
$$
O(n^{1.3··2})
$$
空间复杂度
$$
O(1)
$$
2. 原理解析
建议直接看最下方参考
3.代码剖析
重要参数 gap ,含义 步长 ,这里 gap/=2。这里不做详细剖析,关于步长的分析还有gap=gap/3-1 ,笔者浏览比较少,只是知道这个性能更好,先挖坑在填补。建议查询资料。
private static void shellsort(int[] array) {
int i = 0, j = 0;
int n = array.length;
int gap = array.length;
for (gap = gap / 2; gap>0; gap = gap / 2) {
for (i = 0; i < gap; i++) {
// 下面就是直接插入排序
for (j=i+gap; j < n ;j = j + gap){
int k=j-gap;
int tmp=array[j];
if (tmp<array[k]){
for (;k>=0&&array[k]>tmp;k-=gap){
array[k+gap]=array[k];
}
}
array[k+gap]=tmp;
}
}
}
}
添加的循环
for (gap = gap / 2; gap>0; gap = gap / 2) {
for (i = 0; i < gap; i++) {
……
}
}
for (gap = gap / 2; gap>0; gap = gap / 2)
步长解析,最后等于1时,相当于全局的插入排序
for (i = 0; i < gap; i++) {
……
}
gap从另一方面也代表了分组组数,每取一次步长,步长=组数,需要对每一组都进行直接插入排序。
over
参考如果天弄不死,大家多看这个。