zoukankan      html  css  js  c++  java
  • 算法(插入排序----手写5种方法,快进来看看)

    插入排序

    什么是插入排序?
    假设数列第一个元素为已排序数列,剩余数列为未排序将待排序元素挨个插入到已排序数列中每次插入都必须保证数列是有序的,即通过比较和移动有序数列中的元素,将元素插入到合适的位置
    一句话概括:确认有序数列、无序数列 

    具体实现逻辑

    1. 取数组的第一个元素为已经排序好的元素,将第一个元素看作有序序列
    2. 取数组的第二个元素和已经排序好的元素进行比较,如果第二个元素比第一个元
    素小,则交换位置,排序完成后第一个元素和第二个元素必然有序,形成新的有
    序数列
    3. 取数组的第三个元素,依次和第一个第二个元素进行比较,排序完成后第一个,
    第二个,第三个元素形成一个有序数列
    4. 重复取第四个元素,第五个元素,第六个元素。。。
    5. 最后一个元素重复上述步骤,最终实现整个数组有序

     插入排序的核心思想:确认有序数列确定无序数列

    
    方法一:两个for循环实现,分别比较a[i],a[j]的区别
    def insertSort(arr):
        for i in range(1,len(arr)):
            for j in range(0,i):
                if arr[j]>arr[i]:
                    arr[j],arr[i]=arr[i],arr[j]
        return arr
    
    arr=[4,8,1,9,2,7]
    insertSort(arr)
    
    执行结果:

    >>> def insertSort(arr):
    ... for i in range(1,len(arr)):
    ... for j in range(0,i):
    ... if arr[j]>arr[i]:
    ... arr[j],arr[i]=arr[i],arr[j]
    ... return arr
    ...
    >>> arr=[4,8,1,9,2,7]
    >>> insertSort(arr)
    [1, 2, 4, 7, 8, 9]
    >>>

    
    方法二:两个for循环,确定一个要比较的值
    def insertSort(arr):
        for i in range(1,len(arr)):
            value=arr[i]#这里定义一个要比较的值
            for j in range(i,0,-1):
                if arr[j-1]>value:
                    arr[j-1],arr[j]=arr[j],arr[j-1]
        return arr
    
    arr=[4,8,1,9,2,7]
    insertSort(arr)
    执行结果:

    >>> def insertSort(arr):
    ... for i in range(1,len(arr)):
    ... value=arr[i]#这里定义一个要比比较的值
    ... for j in range(i,0,-1):
    ... if arr[j-1]>value:
    ... arr[j-1],arr[j]=arr[j],arr[j-1]
    ... return arr
    ...
    >>> arr=[4,8,1,9,2,7]
    >>> insertSort(arr)
    [1, 2, 4, 7, 8, 9]
    >>>

    
    方法三:外层使用while循环,内层使用for循环
    def insertSort(arr):
        i=1
        while i<len(arr):
            value=arr[i]
            for j in range(i,0,-1):
                if arr[j-1]>value:
                    arr[j-1],arr[j]=arr[j],arr[j-1]
        i+=1
        return arr
    
    arr=[4,8,1,9,2,7]
    insertSort(arr)

    执行结果:

    >>> def insertSort(arr):
    ... i=1
    ... while i<len(arr):
    ... value=arr[i]
    ... for j in range(i,0,-1):
    ... if arr[j-1]>value:
    ... arr[j-1],arr[j]=arr[j],arr[j-1]
    ... i+=1
    ... return arr
    ...
    >>> arr=[4,8,1,9,2,7]
    >>> insertSort(arr)
    [1, 2, 4, 7, 8, 9]
    >>>

    
    
    方法四:两个while循环实现,不要忘记最后要++操作
    def insertSort(arr):
        i=1
        while i<len(arr):
            value=arr[i]
            j=i
            while j>0:
                if arr[j-1]>value:
                    arr[j-1],arr[j]=arr[j],arr[j-1]
                j-=1
        i+=1
        return arr
    
    arr=[4,8,1,9,2,7]
    insertSort(arr)

    >>> def insertSort(arr):
    ... i=1
    ... while i<len(arr):
    ... for i in range(1,len(arr)):
    ... value=arr[i]
    ... j=i
    ... while j>0:
    ... if arr[j-1]>value:
    ... arr[j-1],arr[j]=arr[j],arr[j-1]
    ... j-=1
    ... i+=1
    ... return arr
    ...
    >>> arr=[4,8,1,9,2,7]
    >>> insertSort(arr)
    [1, 2, 4, 7, 8, 9]

    
    方法五:外层for循环,内层while循环实现
    def insertSort(arr):
        for i in range(1,len(arr)):
            j=i
            while j>0:
                if arr[j-1]>arr[j]:
                    arr[j-1],arr[j]=arr[j],arr[j-1]
                j-=1
        i+=1
        return arr
    
    arr=[4,8,1,9,2,7]
    insertSort(arr)

    执行结果:

    >>>
    >>> def insertSort(arr):
    ... for i in range(1,len(arr)):
    ... j=i
    ... while j>0:
    ... if arr[j-1]>arr[j]:
    ... arr[j-1],arr[j]=arr[j],arr[j-1]
    ... j-=1
    ... i+=1
    ... return arr
    ...
    >>> arr=[4,8,1,9,2,7]
    >>> insertSort(arr)
    [1, 2, 4, 7, 8, 9]



    时间复杂度
    • 在最好的情况下,即序列已经是排好序的情况下,每次比较一次就退出while循环,则总比较次数
    
    
    是n-1次,时间复杂度是O(n)
    
    
    • 在最坏的情况下,即每次while循环都要比较到第一个元素,则:
    
    
    • 第一次循环,比较了1次;
    
    
    • 第二次循环,比较了2次;
    
    
    • ...
    
    
    • 第n-1次循环,比较了n-1次;
    
    
    • 总的比较次数是1+2+3+...+(n-1) = n(n-1)/2
    
    
    我们上面所求得的n(n-1)/2,其时间复杂度,最大的影响因子是n2 /2,故其时间复杂度是O(n2)
     
  • 相关阅读:
    VS2010/MFC编程入门之三十八(状态栏的使用详解)
    VS2010/MFC编程入门之三十七(工具栏:工具栏的创建、停靠与使用)
    VS2010/MFC编程入门之三十六(工具栏:工具栏资源及CToolBar类)
    VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
    VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
    VS2010/MFC编程入门之三十三(常用控件:标签控件Tab Control 下)
    走进JDK(十二)------TreeMap
    深入理解java虚拟机(二)-----垃圾回收
    深入理解java虚拟机(一)-----java内存区域以及内存溢出异常
    走进JDK(十一)------LinkedHashMap
  • 原文地址:https://www.cnblogs.com/hzyimen/p/12364738.html
Copyright © 2011-2022 走看看