zoukankan      html  css  js  c++  java
  • 算法学习:希尔排序(插入排序)

    1、插入排序有两种,直接插入排序和希尔排序

    2、希尔排序核心思想

    希尔排序本质也是一种插入排序,但是是根据简单插入排序进行优化有的一种更加高效的版本,别称是缩小增量排序。
    希尔排序的核心思想是将排序数组按照增量进行分组,然后对分组的元素进行直接插入排序,循环缩小分组增量,最后当增量长度为1是排序结束。

    3、举例:给不同身高的人进行排序

    第一步:分组,找一个间隔分组,间隔取4。间隔通常是总长度的一半,奇数偶数均可。

    如图所示:0,4,8一组;1,5一组,2,6一组;3,7一组。

    第二步:对于每组元素,分别进行排序

      第一组:0,4,8  已经排好序;

      第二组:5,1 

      第三组:6,2

      第四种:3,7

    所有组拍完序后,此时:

    第三步:继续设置间隔,这次的间隔是上次的一半,间隔取2

      第一组:0,2,4,6,8

      第二组:1,3,5,7

    第四步:重复步骤二给每组排序:

      第一组:2,0,6,4,8

      第二组:3,7,1,5

    全部排完序后:

    第五步:再次设置间隔,间隔取上次的一半1

    当间隔为1时,使用插入排序法,进行排序

    最终结果:

    方法总结:对每个分组进行插入排序

    4、代码

    对数组[83,29,30,5,99,34,12,66]使用希尔排序进行排序。

    # 代码1

    def shellsort(arr):
        #设置步长
        gap = len(arr)
        while gap > 0:
            #遍历分组
            for i in range(gap,len(arr)):
                #对当前分组的元素进行插入排序
                for j in range(i,gap-1,-gap):
                    if arr[j] < arr[j-gap]:
                        arr[j],arr[j-gap]=arr[j-gap],arr[j]
                    else:
                        break
            print(arr)
            gap //= 2# 步长减半
        return arr
    
    arr=[83,29,30,5,99,34,12,66]
    print("最终结果:",shellsort(arr))

    结果:

    #代码2:分成直接插入排序+希尔排序思想

    def compare(arr,i,gap):
        #直接插入排序
        j = i-gap
        while j>=0:
            if arr[j]>arr[j+gap]:
                arr[j+gap],arr[j]=arr[j],arr[j+gap]
                j-=gap
            else:
                break
    
    
    def shellSort(arr):
        gap=len(arr)//2
        while gap>=1:#步长大于0的时候,都要做以下步骤
            #1 分组
            #2 对分组的元素进行直接插入排序
            #3 缩小步长
            for i in range(gap):#对每组都要进行直接插入排序
                for j in range(i,len(arr),gap):
                    compare(arr,j,gap)
            gap//=2  #一轮循环之后,才调整步长
        return arr
    
    arr=[7,3,45,23,-1,34,88,9,4]
    print(shellSort(arr))
    #结果[-1, 3, 4, 7, 9, 23, 34, 45, 88]

    5、希尔排序的时间复杂度

    希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个素很少,速度很快;
    当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。
    所以希尔排序的时间复杂度比O(n^2)要好一些。

     
     

  • 相关阅读:
    C语言指针入门
    c的动态内存管理
    汇编入门基础与helloworld
    汇编1
    汇编2——完整的例子集合
    算法与数据结构——选择,插入,希尔排序
    MySQL
    MySQL 笔记
    CSS样式优先级
    GIT使用笔记
  • 原文地址:https://www.cnblogs.com/hqq2019-10/p/14085589.html
Copyright © 2011-2022 走看看