图解排序 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 次分组 」
「 利用第 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 - 希尔排序的主要内容,如果未能解决你的问题,请参考以下文章