希尔排序,属于插入排序的一种,是直接插入排序的加强版。在希尔排序中引入了步长(gap)的概念,然而在插入排序中,步长默认为1。正如我们直接堆插入排序的分析,数据集合的排列顺序对插入排序的效率会由很大的影响,而且影响会很大。而希尔排序正是从这个方向对直接插入排序进行加强。
基本概念:
将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,
对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行
排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。
即,希尔排序是将数据集合按照步长gap相隔的子数据组成多个子数据集合,再进行直接插入
排序,最后以步长为1来进行排序,此时gap为1的排序过程和直接插入排序复杂的不是一个级别的
复杂度。
框架分析:
希尔排序最外层的循环是步长的递减的循环,内循环就是直接插入排序算法了,不过这个和
普通的直接插入排序算法不一样,这个步长gap为最外层循环的循环节点值(gap)。其他的情况
和概念同直接插入排序一样。
算法稳定性:
这个算法是不稳定的,再数据集合中,相等的数据在排序的过程中相对位置会发生变化。
代码实现:
/*
* 希尔排序
*/
public static void shellSort(){
int n = 0 ;
//获取最大希尔排序步数
while(n <= array.length)
{
n = n*3 +1;
}
while(n > 0)
{
for(int i = n ; i < array.length; i+=1)
{
int j = i - n;
int temp = array[i];
while(j>=0&&array[j]>temp){
array[j + n] = array[j];
j = j - n;
}
array[j + n] = temp;
}
n = (n -1)/3;
}
}
图文解析:略(同直接插入排序一样)
算法复杂度分析:
希尔排序复杂度和补偿序列的选取相关,如左下所示:
步长序列 | 最坏情况下复杂度 |
| |
| |
| |
与其他算法比较:
处理大数据排序的时候,效率是比不上快速排序的;
希尔排序比直接插入排序比较次数和移动次数都少很多,数据量越大效果越明显;
直接插入排序是稳定的,希尔排序是不稳定的;