相关特点
- 最坏时间复杂度为o(n^2)
- 最好时间复杂度为o(n^1.3)
- 平均时间复杂度为o(nlogn)~o(n^2)
- 平均空间复杂度为o(1)
- 不稳定
基本思想
1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,不会有大幅度的移动,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
算法描述
将整个待排序的记录序列以一定间隔分割成为若干子序列分别进行直接插入排序,具体算法描述:
- 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
- 按增量序列个数k,对序列进行k 趟排序;
- 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
重点:
- 间隔的计算:间隔h的初始值为1,通过h=h*3+1来循环计算,直到间隔大于数组的大小时停止。最大间隔为不大于数组大小的最大值
- 间隔的减少:h=(h-1)/3
图解:
代码实现
package Sort;
/**
* 希尔排序
* @author Dan
*
*/
public class ShellSort {
/**
* 希尔排序
*/
public static void sort(long[] arr){
//初始化间隔
int h =1;
//计算最大间隔,3h+1<数组大小,3h<数组大小,所以可以得到下面的h<arr.length/3
while(h<arr.length/3){
h=h*3+1;
}
while(h>0){
//进行插入排序
long temp = 0;
for (int i = h; i < arr.length; i++) {
temp = arr[i];
int j=i;
while (j>h-1 && arr[j-h]>=temp) {
arr[j]=arr[j-h];
j=j-h;
}
arr[j]=temp;
}
h=(h-1)/3;
}
}
}
各算法详解可参考https://www.cnblogs.com/onepixel/articles/7674659.html