美文网首页
iOS-希尔排序

iOS-希尔排序

作者: 路飞_Luck | 来源:发表于2019-03-25 23:20 被阅读0次
序言

以下内容摘自百度百科 希尔排序

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。

在这之前冒泡、选择、插入排序的时间复杂度基本都是O(n²)的,希尔排序算法是突破这个时间复杂度的第一批算法之一。

算法思想 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 1 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
  • 2 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
基本思想

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量,即所有记录放在同一组中进行直接插入排序为止。

该方法实质上是一种分组插入方法
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。

给定实例的shell排序的排序过程

假设待排序文件有10个记录,其关键字分别是:

49,38,65,97,76,13,27,49,55,04。

增量 依次取值为 5,2,1

image.png

解释说明
希尔排序在插入排序的基础上增加一个叫增量的概念。那什么增量?插入排序只能与相邻的元素进行比较,而希尔排序则是进行跳跃比较,而增量就是步长。比如增量为5时,下标为0的元素与下标为5的元素比较,5再与10比较,1与6比较,6再与11比较……比较完后,再去减少增量,重复之前步骤,直到增量为1,此时只有一个分组了,再对这一个分组进行插入排序,整个希尔排序就结束了。

范例代码

// 起始间隔值gap设置为总数的一半,直到 gap==1 结束
-(void)shellSort:(NSMutableArray *)list{
    int gap = (int)list.count / 2;  // 初始增量
    while (gap >= 1) {
        for(int i = gap ; i < [list count]; i++){
            NSInteger temp = [[list objectAtIndex:i] intValue];
            int j = i;
            
            // 以下就是一个直接插入比较算法,只是直接插入比较的增量为1,希尔排序的增量为gap罢了
            // j >= gap 因为增量为gap,所以只有当j >= 增量时,才有必要进行比较
            // [j - gap] 因为gap为增量,每次都是以增量为跨度进行比较的
            while (j >= gap && temp < [[list objectAtIndex:(j - gap)] intValue]) {
                // 将比较大的数据移动到j位置上
                [list replaceObjectAtIndex:j withObject:[list objectAtIndex:j-gap]];
                // 往前移动增量个数,进行比较
                j -= gap;
            }
            // 将待排序值插入j位置上
            [list replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];
        }
        NSLog(@"%@",[self getArrayStr:list]);
        gap = gap / 2;
    }
}

// 将数组中的元素拼接成字符串 - 方便打印
- (NSString *)getArrayStr:(NSArray *)array {
    NSMutableString *strM = [NSMutableString string];
    for (NSNumber *num in array) {
        [strM appendString:[NSString stringWithFormat:@"%@,",num]];
    }
    return strM.copy;
}

将待排序的数组进行希尔排序

NSArray *array = @[@3,@2, @6, @9, @8, @5, @7, @1, @4];
[self shellSort:[NSMutableArray arrayWithArray:array]];

运行结果


image.png

算法详细画图分解:

image.png
增量的说明

因为增量的选择是希尔排序的重要部分, 所以摘出来单独说明。

已知的最好增量序列是由Sedgewick提出的 1,5,19,41,109,...

它是由交错两个序列的元素获得:<公式: 9(4 ķ - 2 ķ)+ 1 和 2 K + 2(2 K + 2 - 3)+ 1 >
1,19,109,505,2161,... ...,|| 9(4 ķ - 2 ķ)+ 1,K = 0,1,2,3,... 5,41,209,929,3905,... ..|| 2 K + 2(2 K + 2 - 3)+ 1,K = 0,1,2,3,...

用这样增量序列的希尔排序比插入排序要快,甚至在小数组中比快速排序和堆排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。

稳定性

由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

时间性能
  • 1 增量序列的选择

Shell排序的执行时间依赖于增量序列。

好的增量序列的共同特征:

  • 最后一个增量必须为1;
  • 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。

有人通过大量的实验,给出了较好的结果:当n较大时,比较和移动的次数约在nl.25到1.6n1.25之间。

  • 2 Shell排序的时间性能优于直接插入排序

希尔排序的时间性能优于直接插入排序的原因

  • 当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。
  • 当n值较小时,n和 n * n 的差别也较小,即直接插入排序的最好[时间复杂度]O(n)和最坏时间复杂度0(n*n)差别不大。
  • 在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。

因此,希尔排序在效率上较直接插入排序有较大的改进。

希尔排序复杂度分析:

在最坏的情况下时间复杂度仍为O(n²),而使用最优的增量在最坏的情况下却为O(n²⁄³)。需要注意的是,增量序列的最后一个增量值必须等于1才行。另外由于记录是跳跃式的移动,希尔排序并不是一种稳定的排序算法。


本文参考 iOS算法总结-希尔排序


项目链接地址 - ShellSortDemo

相关文章

  • iOS-希尔排序

    序言 以下内容摘自百度百科 希尔排序 希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(D...

  • 排序算法(二)之希尔排序

    图解排序算法(二)之希尔排序 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也...

  • 07-希尔排序(Shell Sort)

    希尔排序(Shell Sort) 希尔排序是唐纳德·希尔(Donald Shell)在0959年提出的。希尔排序与...

  • 排序-希尔排序(分治)

    希尔排序 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。 希尔排序...

  • swift经典算法-希尔排序

    希尔排序 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。 希尔排序...

  • 排序算法④——希尔排序

    希尔排序 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。 希尔排序...

  • 排序算法-希尔排序(Java实现)

    希尔排序 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是...

  • 说说算法那些事-希尔排序

    希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,希尔排序法又称...

  • 希尔排序学习

    希尔排序希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。希尔排序是基...

  • 排序算法(四) 希尔排序(插入排序的进化)

    参考Java排序算法(四):希尔排序常见排序算法 - 希尔排序 (Shell Sort) 希尔排序算法是按其设计者...

网友评论

      本文标题:iOS-希尔排序

      本文链接:https://www.haomeiwen.com/subject/uvtivqtx.html