算法介绍
从上一篇《插入排序》可以知道,当最小元素恰好在最后一个时,需要移动的次数为N-1。当一个从大到小排列的数组使用插入排序变成从小到大排列时,需要比乱序状态下耗费更多的时间。原因为插入排序是从后往前一位一位的往前交换,如果能把靠后的较小元素只交换(移动)一次就插入到靠前位置,则能有效的缩短排序时间。希尔排序就是这样一种算法。
希尔排序通过一个序列让靠后的元素一次性移动到前面,最后使用插入排序让数组变成有序状态。
举个例子。长度为100的数组,挑选出[1,10,20,50]这么一个序列,这个数列的含义就是每次元素移动的间隔。
- 让间隔50的数据相对有序(arr[0]<arr[49]<arr[99])
- 让间隔20的数据相对有序(arr[0]<arr[19]<arr[39]<arr[59]<arr[79]<arr[99])
- 让间隔10的数据相对有序(arr[0]<arr[9]<arr[19]<arr[29]<arr[39]……)
- 让间隔1的数据现对有序(步长为1实际上就是插入排序)
下图为《算法》第四版上希尔排序排序轨迹样例:
这张图是对SHELLSORTEXAMPLE字符序列排序,序列为13、4、1。
可视化效果:这里
Javascript实现
1 |
|
Java实现
1 |
|
总结
- 不稳定。
- 原地排序。
- 时间复杂度为:目前无法准确评估时间复杂度。但是肯定小于平方级别,大于线性对数级别。详细可见《算法》第四版P162
- 空间复杂度为:常数级别。
- 希尔排序比插入排序、选择排序更快。且数组越大,优势越大。
- 对于递增序列可以随意选择,目前无法证明某个序列是最优的。
GitHub:https://github.com/AlbertKnag/algs-practice
上一篇:排序算法03:插入排序
下一篇:排序算法05:归并排序