zoukankan      html  css  js  c++  java
  • 插入排序

    插入排序

    原理

    一句话概括:依次选择一个待排序的数据,插入到前边已排好序的序列中。

    1.从数组的第二个数据开始往前比较,即一开始用第二个数和他前面的一个比较,如果 符合条件(比前面的大或者小,自定义),则让他们交换位置。

    2.然后再用第三个数和第二个比较,符合则交换,但是此处还得继续往前比较,比如有 5个数8,15,20,45, 17,17比45小,需要交换,但是17也比20小,也要交换,当不需 要和15交换以后,说明也不需要和15前面的数据比较了,肯定不需要交换,因为前 面的数据都是有序的。

    3.重复步骤二,一直到数据全都排完。

    性能

    时间复杂度为O(N^2),空间复杂度为O(1)。算法是稳定的,比较次数和交换次数都与初始序列有关。

    优化

    直接插入排序每次往前插入时,是按顺序依次往前找,可在这里进行优化,往前找合适的插入位置时采用二分查找的方式,即折半插入(二分查找插入)。
    折半插入排序相对直接插入排序而言:平均性能更快,时间复杂度降至O(NlogN),排序是稳定的,但排序的比较次数与初始序列无关,总是需要foor(log(i))+1次排序比较。

    使用场景

    当数据基本有序时,采用插入排序可以明显减少数据交换和数据移动次数,进而提升排序效率。

    算法适用于少量数据的排序。

    直接插入排序

    def insertsort(mylist):
        length = len(mylist)
        if length <= 1:
            return mylist
        
        # 只有列表长度大于1时才需要比较插入,i为列表的第i个元素,需要依次和前面的i-1个数做比较插入
        for i in range(1, length):
            j = i - 1
            # 如果当前值小于前一个元素,将当前值存储于一个临时变量中,将前一个元素后移一位
            if mylist[i] < mylist[j]:
                tmp = mylist[i]
                mylist[i] = mylist[j]
                
                # 继续将tmp和更前面一位元素比较,如果元素值比tmp值大,则后移一位
                j -= 1
                while j >= 0 and tmp < mylist[j]:
                    mylist[j+1] = mylist[j]
                    j -= 1
                
                mylist[j+1] = tmp
        return mylist
            
    mylist = [48, 38, 65, 97, 76, 13, 27, 49]
    print(insertsort(mylist))
    
    def insert_sort(lists):
        count = len(lists)
        if length <= 1:
            return mylist
        
        for i in range(1, count):
            # 将当前值存入临时变量中
            key = lists[i]
            j = i - 1
            while j >= 0:
                # 如果当前值小于前一个元素,将前一个元素后移一位
                if lists[j] > key:
                    lists[j + 1], lists[j] = lists[j], key
                j -= 1
        return lists
            
    mylist = [48, 38, 65, 97, 76, 13, 27, 49]
    print(insert_sort(mylist))
  • 相关阅读:
    LeetCode 35 搜索插入位置
    LeetCode 69 x 的平方根
    LeetCode 61 旋转链表
    LeetCode 876 链表的中间结点
    LeetCode 142 环形链表 II
    LeetCode 206 反转链表
    LeetCode 237 删除链表中的节点
    LeetCode 83 删除排序链表中的重复元素
    元素的隐藏与显示与判断 js jquery aspx.cs
    判断对象是否为空 js与Jquery区别
  • 原文地址:https://www.cnblogs.com/lianhaifeng/p/13493709.html
Copyright © 2011-2022 走看看