图解排序 3/10 - 希尔排序

Posted 超越技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图解排序 3/10 - 希尔排序相关的知识,希望对你有一定的参考价值。

希尔排序,它是由 D.L.Shell 于1959 年提出而得名。根据它的名字很难想象算法的核心思想。[ 所以只能死记硬背了,面试官问:希尔排序的思想是什么?]。它的核心思想是把一个序列分组,对分组后的内容进行,这里的分组只是逻辑上的分组,不会重新开辟存储空间。它其实是插入排序的优化版,插入排序对基本有序的序列性能好,希尔排序利用这一特性把原序列分组,对每个分组进行排序,逐步完成排序。

希尔排序

以 arr = [ 8, 1, 4, 6, 2, 3, 5, 7 ] 为例,通过 floor(8/2) 来分为 4 组,8 表示数组中元素的个数。分完组后,对组内元素进行插入排序。


「 第1次分组 」

「 利用第 1 次分组结果进行第 2 次分组

图解排序 3/10 - 希尔排序

「 利用第 2 次分组结果进行最后一次分组

代码

+ (NSArray *)shellSort:(NSArray *)unsortDatas { NSMutableArray *unSortArray = [unsortDatas mutableCopy]; // len = 9 int len = (int)unSortArray.count; // floor 向下取整,所以 gap的值为:4,2,1 for (int gap = floor(len / 2); gap > 0; gap = floor(gap/2)) { // i=4;i<9;i++ (4,5,6,7,8) for (int i = gap; i < len; i++) { // j=0,1,2,3,4 // [0]-[4] [1]-[5] [2]-[6] [3]-[7] [4]-[8] for (int j = i - gap; j >= 0 && [unSortArray[j] integerValue] > [unSortArray[j+gap] integerValue]; j-=gap) { // 交换位置 NSNumber *temp = unSortArray[j]; unSortArray[j] = unSortArray[gap+j]; unSortArray[gap+j] = temp; } } } return [unSortArray copy];}

特点

稳定性:它可能会把相同元素分到不同的组中,那么两个相同的元素就有可能调换相对位置,故不稳定

空间复杂度:由于整个排序过程是在原数据上进行操作,故为 O(1);

时间复杂度

希尔排序的时间复杂度与增量序列的选取有关,例如希尔增量时间复杂度为O(n²),而Hibbard增量的希尔排序的时间复杂度为O(log n的3/2),希尔排序时间复杂度的下界是n*log2n

百度百科

感想


希尔排序在整个过程中,分组方式为:group = length/2,  group/2 ...... 1,直到只能分一组,在整个分组过程中使元素逐渐变得有序,这样使用插入排序的时候就不需要移动大量元素,比如一个逆序序列 arr = [6, 5, 4, 4, 2, 1],采用插入排序每次需要移动大量元素,如果换成希尔排序移动次数就会减少。希尔排序一个有意思的点是采用不同方式进行分组(上面提到的是采用的希尔增量分组),时间复杂度会有所不同,有兴趣的读者可以了解下其它分组方式。



推荐阅读:



探索技术之外的生活



以上是关于图解排序 3/10 - 希尔排序的主要内容,如果未能解决你的问题,请参考以下文章

图解排序算法:希尔排序

图解排序算法之希尔排序

图解排序算法之希尔排序

图解排序算法之希尔排序

排序算法——希尔排序的图解代码实现以及时间复杂度分析

图解排序算法-希尔排序