zoukankan      html  css  js  c++  java
  • python 排序 插入排序与希尔排序

    希尔排序是插入排序的升级版,先来了解插入排序

    插入排序

    算法思想:

      插入排序再面对几乎已经有序的数据效率非常高,可以达到线性排序的效率

      将数组元素插入已经有序的部分中,具体的过程是在有序的部分中通过比较找到新插入元素应该插入的位置,然后从有序部分的队尾元素开始,统统向后移动一位(这一位原本是刚刚那个元素的位置)直到应改插入的那个地方给腾出来,将元素放进去,重复上述过程,直到所有元素有序

    def insertion_sort4(collection):
        length=len(collection)
        #外层循环负责从前到后,将所有元素向前插入
        for loop_index in range(1,length):
            #内层循环负责在已经有序的序列中找到位置
            current_element=collection[loop_index]
            #改进以更高效的处理有序(只能对升序或者降序的一种)
            if current_element>=collection[loop_index-1]:
                continue
            for i in range(loop_index):
                if collection[i]>current_element:#不选择等于,可以向后少移
                    #移动出位置
                    for j in range(loop_index,i,-1):
                        #不选择从后往前交换,而是移动
                        collection[j]=collection[j-1]
                    collection[i]=current_element
                    break
        return collection
    

      算法性能: 最优时间复杂度:O(n^2);最坏时间复杂度O(n^2);平均时间复杂度O(n^2)

           原地排序,稳定和不稳定都能上面的是稳定的

    比较:

      随机数据(1000):运行100次,与快速排序比较,比快排慢一个数量级

    详细数据:[0.02998447418, 0.03126454353, 0.03298068047, 0.03098273277, 0.0309882164, 0.03198075294, 0.03298044205, 0.03097939491, 0.03298044205, 0.03096532822, 0.03296637535, 0.03098273277, 0.031988
    14392, 0.03198170662, 0.02998304367, 0.03198099136, 0.03198194504, 0.03098273277, 0.03129839897, 0.03198194504, 0.03198242188, 0.03304195404, 0.03298139572, 0.03397989273, 0.03098106384, 0.03098225594, 0.03298139572, 0.03297972679, 0.0310177803, 0.03232741356, 0.03198122978, 0.03098225594, 0.03198099136, 0.03098249435, 0.03098201752, 0.03397893906, 0.03098201752, 0.02998447418, 0.03198170662, 0.0309817791, 0.03298139572, 0.0319814682, 0.03198027611, 0.03198075294, 0.03298068047, 0.03215503693, 0.03098106384, 0.03198122978, 0.0319814682, 0.03098297119, 0.03198385239, 0.03198289871, 0.03198218346, 0.03234624863, 0.03198075294, 0.03098201752, 0.03298807144, 0.03098058701, 0.03098154068, 0.03098106384, 0.03098273277, 0.03198075294, 0.03198075294, 0.03098034859, 0.0321495533, 0.03198504448, 0.03298187256, 0.03198218346, 0.03198099136, 0.02998280525, 0.0319814682, 0.03098416328, 0.03098154068, 0.03397893906, 0.03198099136, 0.03331136703, 0.03198075294, 0.03198051453, 0.03098082542, 0.03198099136, 0.03298044205, 0.03497982025, 0.03198122978, 0.0319814682, 0.03497815132, 0.03497886658, 0.03298139572, 0.03198099136, 0.03099918365, 0.03297901154, 0.03299331665, 0.03199267387, 0.0319890976, 0.03297424316, 0.03127980232, 0.03294634819, 0.03094792366, 0.03395628929, 0.03296804428, 0.03299927711]
    运行了100次,平均运行时间差(me-other)/(bubble-quick)(正数代表你是个弟弟)是:0.03200459957
    前者(插入排序)平均运行时间0.03376406193,后者(快排)平均运行时间0.00175946236,前者约是后者的19.1900倍
    

      

      与选择排序比较,比选择排序快一半

    详细数据:[-0.04897117615, -0.05092978477, -0.04897165298, -0.04997181892, -0.04597568512, -0.05196714401, -0.04897165298, -0.04797005653, -0.0479722023, -0.0489730835, -0.0529692173, -0.05296993256
    , -0.04297542572, -0.04998970032, -0.0499894619, -0.04997038841, -0.04599285126, -0.04995369911, -0.04894709587, -0.0499458313, -0.05196213722, -0.04893517494, -0.05195713043, -0.0509455204, -0.05097126961, -0.04797315598, -0.04997229576, -0.05100440979, -0.04995894432, -0.05094909668, -0.04797363281, -0.04899024963, -0.05000472069, -0.05099892616, -0.05095696449, -0.04995822906, -0.04898285866, -0.05094671249, -0.04994940758, -0.04894113541, -0.05093574524, -0.05198144913, -0.05096340179, -0.04999995232, -0.04898786545, -0.04995727539, -0.05194878578, -0.04994487762, -0.04897165298, -0.04999732971, -0.04838752747, -0.0509853363, -0.04996991158, -0.04995727539, -0.05197072029, -0.05199098587, -0.04898548126, -0.04898786545, -0.04996991158, -0.0499727726, -0.05294942856, -0.05097031593, -0.04997706413, -0.04994726181, -0.05197072029, -0.04798436165, -0.05097079277, -0.05095767975, -0.0499651432, -0.05096721649, -0.04897141457, -0.04895305634, -0.04997110367, -0.0509967804, -0.04997372627, -0.04997205734, -0.04995822906, -0.05198216438, -0.04995846748, -0.0509455204, -0.04898524284, -0.04997134209, -0.0499587059, -0.04998278618, -0.04897117615, -0.05296874046, -0.0509724617, -0.04797387123, -0.049949646, -0.04797267914, -0.04998350143, -0.05198264122, -0.04997396469, -0.04997444153, -0.05096530914, -0.05196070671, -0.04997181892, -0.04898834229, -0.04998731613, -0.04998636246]
    运行了100次,平均运行时间差(me-other)/(bubble-quick)(正数代表你是个弟弟)是:-0.05001399517
    前者(插入排序)平均运行时间0.03409122467,后者(冒泡)平均运行时间0.08410521984,前者约是后者的0.4053倍
    

      

    希尔排序

    希尔排序是插入排序的升级,他是基于插入排序的两个特点进行改进的:

      插入排序再面对几乎已经有序的数据效率非常高,可以达到线性排序的效率

      但是插入排序再面对随机数据时,一般是比较低效的,因为插入排序一次只能将数据移动一位

    基于如此,希尔排序通过将序列分为几个部分来提升插入排序的性能,这样就可以让一个元素一次性的朝最终位置移动一大步,然后再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这一步,算法基本上是有序的了,此时插入排序的效率较高

    版本1

    def shell_sort4(collection):
        '''自己写的 时间为最快的1.5倍 1000个随机数据平均用时0.047s'''
        #希尔排序是插入排序的改进,改进之处在于希尔排序加入了间隙。假如序列有4个值,间隙是2的话,则第1个元素就会和第1+2个元素做比较
        length=len(collection)
        gaps=[929,509,209,109,41,19,5,1]
        #控制间隙
        for gap in gaps:
            if gap>=length:
                continue
            #遍历一个间隙中的不同元素
            for index_of_gap in range(gap):
                #按间隙去步进形成的小数组
                for k in range(index_of_gap+gap,length,gap):#都是下标
                    #接下来就是普通的插入了
                    #遍历已经有序的,找到应该插入的位置
                    temp=collection[k]
                    for element_index in range(k-gap,index_of_gap-gap,-gap):#直接从这个元素前面的一个比较,记得将他是最小的两种单独考虑
                        if collection[element_index]>temp:
                            collection[element_index+gap]=collection[element_index]#将这个放在上面,
                            collection[element_index]=temp
                        else:
                            break
    

      算法分析:

    版本2(速度快)

    自己对这个版本的认识:

    第一次:
    首先,从index=gap处开始,前面已经有一个元素了,然后用collection[j]与collection[j-gap]比较,即向前比较(之所以向前是再比较和移位一同进行)
    最骚的是这个i++,这个步进真的太妙了,这样步进虽然不能体现出 序列按照等于gap的步长分成的列表 元素之间连续比较,但他体现出了另一方面的连续性
    第二次:
    先定义步长,然后从第二个间隙里的第一个元素开始,向后走,那怎么遍历第一个间隙里的元素呢,这就是巧妙之处了,结合插入元素的操作是从后向前,
    边遍历,边向前移动的步骤,顺道就向前把第一个间隙里的元素给比较了,然后i在向后++遍历
     
    def shell_sort3(collection):
        """别人写的 时间为最快的1倍 1000个随机数据平均用时0.033s
        """
        # Marcin Ciura's gap sequence
        # gaps = [909, 529, 209, 109, 41, 19, 5, 1]
        gaps = [701, 301, 132, 57, 23, 10, 4, 1]
        for gap in gaps:
            i = gap
            while i < len(collection):
                temp = collection[i]
                j = i
                while j >= gap and collection[j - gap] > temp:
                    collection[j] = collection[j - gap]
                    j -= gap
                collection[j] = temp
                i += 1
    
        return collection
    

      算法分析:

    对比

      与插入排序:是插入排序花费时间的十分之一

    详细数据:[-0.0289850235, -0.02998423576, -0.02898454666, -0.02898287773, -0.02898335457, -0.02998304367, -0.02998304367, -0.02998232841, -0.02998185158, -0.02998232841, -0.0299847126, -0.0289838314
    1, -0.02898263931, -0.02898287773, -0.02998232841, -0.02898406982, -0.03000092506, -0.02998280525, -0.02998304367, -0.02998280525, -0.02998352051, -0.02898335457, -0.02998137474, -0.02998232841, -0.03098320961, -0.02998423576, -0.02898311615, -0.02898335457, -0.02898216248, -0.02898478508, -0.02998256683, -0.02998352051, -0.02998209, -0.02898359299, -0.02898359299, -0.02998399734, -0.02998232841, -0.02998065948, -0.0299847126, -0.02898597717, -0.0299847126, -0.02998256683, -0.02898359299, -0.02998352051, -0.02998352051, -0.02998161316, -0.03197932243, -0.02998209, -0.0329823494, -0.02898359299, -0.02898335457, -0.02997040749, -0.02898216248, -0.02996635437, -0.02798318863, -0.02999806404, -0.03098273277, -0.02998328209, -0.02898406982, -0.02998328209, -0.02898263931, -0.02998328209, -0.03098273277, -0.02998280525, -0.02998352051, -0.02898359299, -0.02998256683, -0.03098201752, -0.03098249435, -0.02998399734, -0.03098273277, -0.02998423576, -0.02998256683, -0.02898311615, -0.02898311615, -0.02998209, -0.03098249435, -0.02998256683, -0.02998328209, -0.02798438072, -0.02998399734, -0.03098297119, -0.02998304367, -0.02998256683, -0.02998256683, -0.02998280525, -0.02898335457, -0.02998447418, -0.03097033501, -0.03098726273, -0.02998900414, -0.02997112274, -0.02900028229, -0.03095006943, -0.02998447418, -0.03094172478, -0.0309817791, -0.02798366547, -0.02998328209, -0.02998304367]
    运行了100次,平均运行时间差(shell_sort3-insertion_sort4)(正数代表你是个弟弟)是:-0.02983242989
    前者(shell_sort3)平均运行时间0.00316838264,后者(insertion_sort4)平均运行时间0.03300081253,前者约是后者的0.0960倍
    

      与效率最高的快排对比 花费时间是快排的1.4倍

    详细数据:[0.00099945068, 0.00099921227, 0.00100469589, 0.00101900101, 0.00097775459, 3.385544e-05, -9.5367e-07, 0.00099849701, 0.00099873543, -2.3842e-07, 0.0009996891, 0.0009996891, -4.7684e-07, 0
    .00200009346, 0.00099825859, 0.00099897385, 0.00099897385, -2.3842e-07, 0.00099897385, 0.00099945068, 0.00100421906, -2.3842e-07, 0.00099945068, 0.00099849701, 0.00099992752, 0.00099945068, 0.00100064278, 0.00199866295, 0.0009996891, 7.1526e-07, 0.00099897385, 0.00099992752, 0.0009996891, 0.00100016594, 0.00100040436, -1.19209e-06, 0.00101828575, 0.00099921227, 0.00098085403, 0.00099921227, 0.00098109245, 0.00099945068, 0.00101828575, 0.0009663105, 7.1526e-07, -2.0504e-05, -4.7684e-07, 0.00099754333, 0.00198745728, 0.00101566315, 0.00099897385, 7.1526e-07, 0.00100898743, 0.00099992752, -1.811981e-05, 0.00103330612, 0.0010175705, 0.00199890137, 0.00399708748, 0.00099778175, 0.00099945068, 0.00199961662, 0.0009996891, 0.00199985504, 0.0, 0.00099945068, 0.00099897385, 0.00099897385, 0.00100040436, 0.00099945068, 0.00099921227, 0.00199818611, 0.00099945068, 0.00099945068, 0.00099873543, 0.0009996891, 0.0009996891, 0.00100040436, 0.00100040436, -4.7684e-07, 0.00099945068, -1.43051e-06, 0.00100159645, 0.00099945068, 0.0, 0.00199866295, 0.00099945068, -1.43051e-06, 0.00099992752, -3.57628e-06, -2.86102e-06, 0.00099945068, 0.00099992752, 0.0009996891, 0.00099921227, 0.00099873543, 0.00100040436, -1.66893e-06, 0.00099945068, 0.00099897385]
    运行了100次,平均运行时间差(shell_sort3-quick_sort3)(正数代表你是个弟弟)是:0.00089974642
    前者(shell_sort3)平均运行时间0.00335812569,后者(quick_sort3)平均运行时间0.00245837927,前者约是后者的1.3660倍
    

      与归并相比:比归并稍稍快

    详细数据:[1.430511e-05, -0.00102305412, -3.57628e-06, -2.3842e-07, -1.859665e-05, 1.40667e-05, 2.527237e-05, -2.14577e-06, -0.0010008812, 0.00101470947, 9.05991e-06, -0.00098705292, 1.239777e-05, 0
    .00097060204, -0.0009739399, -0.00099992752, -0.00097465515, -0.00098466873, -0.00097370148, 4.7684e-07, -0.00101256371, -0.00098800659, -1.311302e-05, -0.00099945068, 1.192093e-05, -0.00102496147, -9.5367e-07, -0.00099897385, 1.43051e-06, -9.5367e-07, -7.1526e-07, -7.1526e-07, -0.00101351738, 0.00099802017, -0.0010266304, -0.00100064278, 1.263618e-05, -0.0009996891, -1.19209e-06, -0.0009791851, -1.835823e-05, -1.215935e-05, -0.00100636482, -0.00099992752, 0.00099897385, -0.00100040436, 2.3842e-07, 2.3842e-07, 1.692772e-05, -2.3842e-07, 2.3842e-07, -2.3842e-07, -7.1526e-07, -0.00099992752, 0.0, -2.3842e-07, -0.00099992752, -0.00099992752, 2.3842e-07, 7.1526e-07, 7.1526e-07, 1.43051e-06, -0.00200939178, -0.00100946426, -0.00099945068, -9.5367e-07, 0.0, -0.00099992752, 2.3842e-07, 0.0, 2.3842e-07, 0.00099945068, 0.0, 0.0, -2.3842e-07, 0.00099992752, -0.00100064278, -2.3842e-07, -2.3842e-07, -2.3842e-07, 0.00099992752, -0.00100421906, 0.00099349022, 9.53674e-06, -4.7684e-07, -0.00099921227, -0.00200009346, -4.7684e-07, -0.00100016594, -0.00100016594, -0.00100016594, -0.00100040436, 7.1526e-07, -0.00099945068, -9.5367e-07, 0.0, 4.7684e-07, -0.00099921227, -9.5367e-07, -7.1526e-07]
    运行了100次,平均运行时间差(shell_sort3-merge_sort3)(正数代表你是个弟弟)是:-0.00031960964
    前者(shell_sort3)平均运行时间0.00328832865,后者(merge_sort3)平均运行时间0.00360793829,前者约是后者的0.9114倍
    

      与选择排序 ,面对随机数据时,选择排序的效率和插入排序差不多 都是O(n^2),这里也一样,希尔排序花费的时间是选择的十分之一

    详细数据:[-0.03298163414, -0.03198122978, -0.03397941589, -0.03295445442, -0.03198170662, -0.03298163414, -0.03096294403, -0.03398036957, -0.03198027611, -0.03298377991, -0.03198385239, -0.03397989
    273, -0.03298139572, -0.03198218346, -0.0339922905, -0.03198218346, -0.03198170662, -0.03198194504, -0.03198242188, -0.03298139572, -0.03296518326, -0.03201627731, -0.03197407722, -0.03198027611, -0.03399753571, -0.03299355507, -0.03299427032, -0.03296422958, -0.03094744682, -0.03298926353, -0.03198218346, -0.03298068047, -0.0339949131, -0.03198122978, -0.03195524216, -0.03198194504, -0.03398108482, -0.03295278549, -0.03298091888, -0.03298163414, -0.03198313713, -0.0329823494, -0.03198027611, -0.03098201752, -0.03198170662, -0.03098225594, -0.03098201752, -0.03297996521, -0.03196811676, -0.03298068047, -0.03298139572, -0.03098225594, -0.0309817791, -0.03099441528, -0.03198385239, -0.03096055984, -0.03200674057, -0.03198170662, -0.03199529648, -0.03298258781, -0.03298282623, -0.03198051453, -0.03198122978, -0.03299808502, -0.03198266029, -0.03098225594, -0.03198266029, -0.03198051453, -0.03198170662, -0.03198099136, -0.0329811573, -0.03098273277, -0.03298163414, -0.03298163414, -0.03298068047, -0.0319814682, -0.03198385239, -0.0329811573, -0.03198218346, -0.03198266029, -0.03198027611, -0.03199529648, -0.0329682827, -0.03198170662, -0.03198170662, -0.0329811573, -0.03198242188, -0.03198122978, -0.03098225594, -0.03398084641, -0.03198122978, -0.03196883202, -0.03200554848, -0.032995224, -0.03195738792, -0.03198337555, -0.03198075294, -0.03098320961, -0.0329811573, -0.03298163414]
    运行了100次,平均运行时间差(shell_sort3-select_sort2)(正数代表你是个弟弟)是:-0.03233130693
    前者(shell_sort3)平均运行时间0.00320804119,后者(select_sort2)平均运行时间0.03553934813,前者约是后者的0.0903倍
    

      

      

     

     

  • 相关阅读:
    IntelliJ IDEA 如何在同一个窗口创建多个项目--超详细教程
    spring IOC原理
    java工作错误总结
    java跬步积累
    简单易懂设计模式——简单工厂模式
    Argo 项目入驻 CNCF,一文解析 Kubernetes 原生工作流
    电子书下载 | 超实用!阿里售后专家的 K8s 问题排查案例合集
    在生产环境中,阿里云如何构建高性能云原生容器网络?(含 PPT 下载)
    SIG Cloud Provider Alibaba 网研会第 2 期顺利召开 | 云原生生态周报 Vol. 46
    提问赠书 | 我们请了 7 位云原生专家,等你来问
  • 原文地址:https://www.cnblogs.com/Gaoqiking/p/11169522.html
Copyright © 2011-2022 走看看