一.希尔排序
- 最好时间复杂度 O(n)
- 最坏时间复杂度 O(ns)
- 平均时间复杂度O(nlogn)
- 空间复杂度 O(1)
- 稳定性 不稳定
在详细学习快排和希尔排序后,不得不感叹算法的精妙之处,也让我感受到了算法的乐趣
希尔排序是由一个计算机科学家Donald Shell 发明的 实际上是一个插入排序的优化-- 分组插入排序
二.思路
主要就是逐步折半的增量方法,将数列等分为若干个数值对,并对每个数组对进行比较,将较小的数组对放在前面,粗略的对数列进行排序,
关键变量
- 希尔增量 shellIncrement
- 步数 step
如数列
等量分组,这里5对应的是9,中间间隔4个下标,这里的4就是步数,也就是5往前走4格可以到9这个位置
然后我们把上面同个颜色对应的数值进行排序,共4组,每组中小的值放在前面
然后我们将步数缩小为2,继续进行排序,此时数列被分为2大组,我们需要对2大组进行插入排序即可
排序后为
最后将步数缩小为1进行排序,让插入排序的工作量少了很多
整个过程
三.实现
/**
* 希尔排序
*
* @param array
*/
public static int[] shellSort(int[] array) {
//希尔增量 开始为长度的一半
int shellIncrement = array.length/2;
//步数逐渐减少
for(int step=shellIncrement;step>0;step/=2){
//这里的step同时代表了有几组数列 每组数列都需要单独排序
for(int j=0;j<step;j++){
//这里i=j 代表从哪个数列开始排序,从第一步开始往后走 这样写 可以避免数组越界 并且两辆组队
for(int i=j+step;i<array.length;i+=step){
//对子数列进行插入排序
//等待插入的值
int insertValue = array[i];
//等待被比较插入的值
int temp = array[i-step];
if(insertValue<temp){
array[i] = temp;
array[i-step] = insertValue;
}
}
}
}
return array;
}
算法是自己写的,图的是借鉴他人的 可跳转参考链接看原来的图文解释,很明了
https://zhuanlan.zhihu.com/p/87781731