python学习——插入排序的一个小小优化

插入排序核心:通过构建有序序列,对于未排序序列,在已排序序列中从后向前扫描(对于单向链表则只能从前往后遍历),找到相应位置并插入。实现上通常使用in-place排序(需用到O(1)的额外空间)

  1. 从第一个元素开始,该元素可认为已排序
  2. 取下一个元素,对已排序数组从后往前扫描
  3. 若从排序数组中取出的元素大于新元素,则移至下一位置
  4. 重复步骤3,直至找到已排序元素小于或等于新元素的位置
  5. 插入新元素至该位置
    重复2~5

按照以上分析,我们用python语言可以写出插入排序的代码:

def insertSort(li):
    #插入排序,核心思想是对每一个元素按照从后向前的顺序依次比较大小
    n = len(li)
    if n <= 1:
        return li
    else:
        for i in range(1, n):
            value = li[i]
            index = i
            while li[index-1] > value and index > 0:
                li[index] = li[index - 1]
                index -= 1
            li[index] = value
        return li

在作者电脑上通过对长度为20000的列表进行排序,计算时长为49s。

简单的优化:
通过对插入算法的分析,我们发现,在每次对已知元素与前面的元素进行比较大小时,如果小于前面的,我们就将两者调换位置。这很类似在图书馆放置图书的过程,我们在将借阅的图书放置回原来位置时,是直接锁定该位置,然后将该位置一侧的图书全部移动一部分,最后再将该图书直接插入到该位置上,而不是一本一本的移动。

从这个思想出发,我们可以对插入算法进行适当优化:在while循环中的比较我们并不做元素的交换,只用来记录索引的位置。当确定该元素需要插入的位置后,我们直接将该元素插入到指定位置即可,这样可以省下很多次元素的交换。

通过以上分析,我们可以对源代码进行修改:

def insertSort(li):
    #插入排序,核心思想是对每一个元素按照从后向前的顺序依次比较大小
    n = len(li)
    if n <= 1:
        return li
    else:
        for i in range(1, n):
            value = li[i]
            index = i
            while li[index-1] > value and index > 0:
                index -= 1
            res = li.pop(i)
            li.insert(index, res)
        return li

这里我们通过list.pop()方法移除目标元素,通过list.insert()方法将目标元素插入到指定位置。

同样对长度为20000的列表进行排序,计算时长为29s,节省了40%的时长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值