排序算法专题之希尔排序

Posted Python算法之旅

tags:

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

说在前面

希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n^2)的第一批算法之一。

为什么希尔排序算法的效率会比简单插入排序高?如何理解希尔排序的算法思想?本文拟从“步长为2跳跃式冒泡排序”,到“步长为2跳跃式插入排序”,再到“步长为m跳跃式插入排序”,最后再到“希尔排序”的顺序为大家演示算法的进化过程。


“Python算法之旅”微信群等着你
排序算法专题之希尔排序
排序算法专题之希尔排序
排序算法专题之希尔排序
排序算法专题之希尔排序

扫码加入“Python算法之旅”微信群,和斌哥面对面交流,更多资料和更有趣的话题等你一起来分享。

排序算法专题之希尔排序

希尔排序算法(填空版)

1.  跳跃式冒泡排序(步长为2)

例1.分别对数组a的奇数和偶数位置的元素进行冒泡排序,即采用“跳跃式冒泡”的方法,每次跳跃的步长为2,将数组分成2个子序列,分别对这2个子序列进行排序。

例如,考虑对数组a = [6, 3, 5, 4, 1, 2, 8, 7]进行跳跃式冒泡排序,

排序后的数组a =  [1, 2, 5, 3, 6, 4, 8, 7]。

函数名:jump_bubble_sort(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def jump_bubble_sort(a):

    for i in range(1,            ): #冒泡趟数

        for j in range(          ): #向左扫描

            if a[j] < a[j-2]:

                a[j], a[j-2] = a[j-2], a[j]


2.  跳跃式插入排序(步长为2)

例2.分别对数组a的奇数和偶数位置的元素进行插入排序,即采用“跳跃式插入”的方法,每次跳跃的步长为2,将数组分成2个子序列,分别对这2个子序列进行排序。

例如,考虑对数组a = [6, 3, 5, 4, 1, 2, 8, 7]进行跳跃式插入排序,

排序后的数组a =  [1, 2, 5, 3, 6, 4, 8, 7]。

函数名:jump_insert_sort(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def jump_insert_sort(a):

    for i in range(2, len(a)):

        t, j = a[i], i - 2

        while j >= 0 and a[j] > t:

                       #跳跃式移动,跳跃距离为2

            j -= 2

                      


3.  跳跃式插入排序(步长为m)

例3.跳跃式插入排序(推广到步长为m的情形):将数组a步长为m的元素视为同组元素,将数组分成m个子序列,分别对这m个子序列进行插入排序。

例如,考虑对数组a = [6, 3, 5, 4, 1, 2, 8, 7]进行跳跃式插入排序。

当m=1时,排序后的数组a = [1, 2, 3, 4, 5, 6, 7, 8];

当m=2时,排序后的数组a = [1, 2, 5, 3, 6, 4, 8, 7];

当m=3时,排序后的数组a = [4, 1, 2, 6, 3, 5, 8, 7];

函数名:jump_insert_sort (a, m)

参数表:a -- 待排序列表。m -- 跳跃的步长

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def jump_insert_sort (a, m):

  








4. 
希尔排序

例4.将相隔一定步长的元素组成一个子序列,分别对他们进行插入排序。每完成一轮分组排序后,我们就将步长减半,继续分组排序,直至步长m=1,就变成普通的插入排序了。

函数名:shell_sort(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def shell_sort(a):

    m = len(a) // 2

    while m > 0:

        for i in range(m, len(a)):

            t, j = a[i], i - m

            while j >= 0 and a[j] > t:

                           #跳跃距离为m

                j -= m

            a[j+m] = t

                          #步长m每次减半

希尔排序算法(完整版)

1.  跳跃式冒泡排序(步长为2)

例1.分别对数组a的奇数和偶数位置的元素进行冒泡排序,即采用“跳跃式冒泡”的方法,每次跳跃的步长为2,将数组分成2个子序列,分别对这2个子序列进行排序。

例如,考虑对数组a = [6, 3, 5, 4, 1, 2, 8, 7]进行跳跃式冒泡排序,

排序后的数组a =  [1, 2, 5, 3, 6, 4, 8, 7]。

函数名:jump_bubble_sort(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def jump_bubble_sort(a):

    for i in range(1, (len(a)-1) // 2 + 1): #冒泡趟数

        for j in range(len(a)-1, i*2-1, -1):

            if a[j] < a[j-2]:

                a[j], a[j-2] = a[j-2], a[j]


2.  跳跃式插入排序(步长为2)

例2.分别对数组a的奇数和偶数位置的元素进行插入排序,即采用“跳跃式插入”的方法,每次跳跃的步长为2,将数组分成2个子序列,分别对这2个子序列进行排序。

例如,考虑对数组a = [6, 3, 5, 4, 1, 2, 8, 7]进行跳跃式插入排序,

排序后的数组a =  [1, 2, 5, 3, 6, 4, 8, 7]。

函数名:jump_insert_sort(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def jump_insert_sort(a):

    for i in range(2, len(a)):

        t, j = a[i], i - 2

        while j >= 0 and a[j] > t:

            a[j+2] = a[j] #跳跃式移动,跳跃距离为2

            j -= 2

        a[j+2] = t


3.  跳跃式插入排序(步长为m)

例3.跳跃式插入排序(推广到步长为m的情形):将数组a步长为m的元素视为同组元素,将数组分成m个子序列,分别对这m个子序列进行插入排序。

例如,考虑对数组a = [6, 3, 5, 4, 1, 2, 8, 7]进行跳跃式插入排序。

当m=1时,排序后的数组a = [1, 2, 3, 4, 5, 6, 7, 8];

当m=2时,排序后的数组a = [1, 2, 5, 3, 6, 4, 8, 7];

当m=3时,排序后的数组a = [4, 1, 2, 6, 3, 5, 8, 7];

函数名:jump_insert_sort (a, m)

参数表:a -- 待排序列表。m -- 跳跃的步长

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def jump_insert_sort (a, m):

    for i in range(m, len(a)):

        t, j = a[i], i - m

        while j >= 0 and a[j] > t:

            a[j+m] = a[j] #跳跃式移动,跳跃距离为m

            j -= m

        a[j+m] = t


4.  希尔排序

例4.将相隔一定步长的元素组成一个子序列,分别对他们进行插入排序。每完成一轮分组排序后,我们就将步长减半,继续分组排序,直至步长m=1,就变成普通的插入排序了。

函数名:shell_sort(a)

参数表:a -- 待排序列表。

返回值:该方法没有返回值,但是会对列表的对象按要求排序。

def shell_sort(a):

    m = len(a) // 2

    while m > 0:

        for i in range(m, len(a)):

            t, j = a[i], i - m

            while j >= 0 and a[j] > t:

                a[j+m] = a[j] #跳跃距离为m

                j -= m

            a[j+m] = t

        m //= 2 #步长m每次减半

写在后面

Python排序算法系列文章是我在阅读了大量算法专著以后,尝试用浅陋的语言把自己的理解表达出来。由于本人水平有限,表述中难免出现疏漏甚至错误之处,敬请谅解。

无论是赞同还是反对我的看法,都请你给我留言。如果你有新的想法,千万不要憋在心里,请发出来大家一起讨论。让我们相互学习,共同进步!


需要本文word版的,可以加入“选考VB算法解析”知识星球参与讨论和下载文件,“选考VB算法解析”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。

我们专注选考VB算法,感兴趣就一起来!



相关优秀文章:



以上是关于排序算法专题之希尔排序的主要内容,如果未能解决你的问题,请参考以下文章

排序算法之希尔排序

排序算法总结之希尔排序

图解排序算法之希尔排序

图解排序算法之希尔排序

算法排序算法之希尔排序

排序算法之希尔排序(Java)