zoukankan      html  css  js  c++  java
  • 直接插入排序(python实现)

    这篇博文用来介绍直接插入排序

    直接插入排序基本思想:

    每次将一个待排序的记录插入到已经排好序的数据区中,直到全部插入完为止

    直接插入排序算法思路:

    在直接插入排序中,数据元素分为了有序区和无序区两个部分,在这里我们将列表左边部分作为有序区,列表右边部分作为无序区,有序区和无序区的大小是随着排序的进行而变化的。

    如最开始列表是无序的,所以有序区长度为1,无序区长度为列表长度-1,排序结束后,列表变为有序,则有序区长度为列表长度,无序区长度为0.

    具体步骤为:

    排序过程中每次从无序区中取出第一个元素,将它插入到有序区中的适当位置(即该元素放在此位置,有序区仍然有序),使之成为新的有序区,重复n-1次可完成排序过程。

    假设需要将列表从小到大排序

     想要将从无序区中取出的第一个元素temp插入到有序区中的适当位置,需要有一个循环遍历的过程,即从该元素位置处依次向前比较,会有两种情况:

      1,前面的元素waitsortlist[j-1]大于temp,则temp需要继续向前比较,同时大于temp的元素需要后移一位

      2,前面的元素waitsortlist[j-1]小于等于temp,则temp不需要继续比较了,因为temp大于有序区中最大的元素,有序区伸展一位,包含temp

    另外还需要考虑 j 的边界问题,因为会用到 j-1,所以 j 需要>=1防止越界,对于无序区某一个元素temp的直接插入代码如下:

            temp=waitsortlist[j]
            while j>=1:
                if temp<waitsortlist[j-1]:
                    waitsortlist[j]=waitsortlist[j-1]
                    j=j-1
                else:
                    break
            waitsortlist[j]=temp
    

     外层是一个列表的遍历,加上上面的代码为:

     

        i=0
        j=i+1
        while j<len(waitsortlist):
            temp=waitsortlist[j]
            while j>=1:
                if temp<waitsortlist[j-1]:
                    waitsortlist[j]=waitsortlist[j-1]
                    j=j-1
                else:
                    break
            waitsortlist[j]=temp
            i=i+1
            j=i+1
    

      可以看出,列表的第一个元素必为有序区,遍历的过程中不断扩大有序区的范围,对于列表某一个元素来说,就是将其插入在有序区中适当的位置,外层循环遍历结束后,有序区也扩充为列表长度,即排序结束。

    该算法的时间复杂度为O(n^2),因为有两层循环,时间开销比较大,空间复杂度为O(1),只是用了常数阶的空间来存储变量,用以直接插入排序

    全部代码为(实际上看了前面的相信你已经能写出来了:D

    '''
        直接插入排序
    '''
    def DirectInsertionSort(waitsortlist):
        i=0
        j=i+1
        while j<len(waitsortlist):
            temp=waitsortlist[j]
            while j>=1:
                if temp<waitsortlist[j-1]:
                    waitsortlist[j]=waitsortlist[j-1]
                    j=j-1
                else:
                    break
            waitsortlist[j]=temp
            i=i+1
            j=i+1
        return waitsortlist
    
    
    if __name__=='__main__':
        waitsortlist=[9,8,7,6,5,4,3,2,1,0]
        print(DirectInsertionSort(waitsortlist))
    

      运行结果为:

    直接插入排序 (带监视哨):

    哨兵的概念:一切为简化边界条件而引入的附加结点(元素)均可称为哨兵。

    在上面的代码我们可以看到有这一段:

    while j>=1:
    

      内循环每一次比较前都需要判断 j 是否越界,有没有不需要判断的办法呢?当然有,这就是哨兵的作用

    将上面的代码改为:

    def DirectInsertionSortEye(waitsortlist):
        i=1
        j=i+1
        while j<len(waitsortlist):
            temp=waitsortlist[j]
            waitsortlist[0]=temp
            while temp<waitsortlist[j-1]:
                waitsortlist[j]=waitsortlist[j-1]
                j=j-1
            waitsortlist[j]=temp
            i=i+1
            j=i+1
        return waitsortlist
    
    if __name__=='__main__':
        waitsortlist=[0,9,8,7,6,5,4,3,2,1,0]
        print(DirectInsertionSortEye(waitsortlist))
    

      输出的结果为:

     我们将waitsortlist[0]设置为哨兵,传入列表的时候,该位置也不能够放置有效元素,用列表一个元素的空间判断越界与否的比较时间。可以看出,一次循环少判断一次,n次循环少判断n次,当数据量较大时,很明显是优于不带监视哨的直接插入排序。

    带监视哨的直接插入排序思想也很简单,在原有基础上稍加修改即可,这里不再赘述。

  • 相关阅读:
    12套有用的免费 PSD 格式 Android UI 素材
    使用 Canvas 和 JavaScript 创建逼真的下雨效果
    在网页设计中使用漂亮字体的16个优秀例子
    Koala – 开源的前端预处理器语言图形编译工具
    BackgroundCheck – 根据图片亮度智能切换元素样式
    经典网页设计:18个示例展示图片在网页中的使用
    TogetherJS – 酷!在网站中添加在线实时协作功能
    30个令人惊叹的灵感来自自然风光的网站设计《下篇》
    太有才了!创新的街头涂鸦手绘欣赏【中篇】
    15款美丽的设备模板,帮助展示你的 APP
  • 原文地址:https://www.cnblogs.com/Cl0ud/p/12942704.html
Copyright © 2011-2022 走看看