Python排序算法:插入排序


什么是插入排序

插入排序(Insertion Sort)是一种简单直观的排序算法。
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序在实现上,在从后向前的扫描过程中,需要把已排序元素逐步向后挪位,为最新元素提供插入空间。

插入排序动图

(用MD写的,插入的动图貌似是不会动了。。。。)
从第二位开始,依次和前面的数进行比较,第一位默认已经是有序的了;
第三位和前两位依次比较,第四位和前三位依次比较;
前面的元素均为有序,后面为无序;
即:
先将前两个排序
再将前三个排序
前四个

一直到最末尾




代码实现

def insertion_sort(list):
    n = len(list)
    for i in range(1,n):
        for j in range(i,0,-1):
            if list[j] < list[j-1]:
                list[j],list[j-1] = list[j-1],list[j]
            else:
                break
    return list




解析

def insertion_sort(list):
    n = len(list)
    for i in range(1,n):

首先,得到数据的长度后,开始从 1 遍历整个数据(从 1 开始而不是从 0 开始),因为第一个元素已经是有序的了,所以不用再排序了。

def insertion_sort(list):
    n = len(list)
    for i in range(1,n):
        for j in range(i,0,-1):
            if list[j] < list[j-1]
                list[j],list[j-1] = list[j-1],list[j]

从当前元素开始依次往前扫描
判断与前一位相比大小




优化插入排序

上面的代码中,交换操作很费操作步骤,因为一次交换,相当于 3 次复制,这还不包括内部的函数过程。所以我们可以根据这点进行优化,把原本交换操作,改成赋值语句。

def insertion_sort(list):
    n = len(list)
    for i in range(1, n):
        key = list[i]
        j = i - 1
        while j >= 0 and list[j] > key:
            list[j+1] = list[j]
            j -= 1
        list[j+1] = key
    return list

list1 = [5,6,2,7,9,0,1,3,8,4]
print("原列表:%s" %list1)
insertion_sort(list1)
print("排序后列表:%s" %list1)

>> 原列表:[5, 6, 2, 7, 9, 0, 1, 3, 8, 4]
   排序后列表:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

优化后代码解析

def insertion_sort(list):
    n = len(list)
    for i in range(1, n):
        key = list[i]
        j = i - 1

首先,遍历列表每一位,然后用 key 保存当前位置的值; j 表示前一位;

def insertion_sort(list):
    n = len(list)
    for i in range(1, n):
        key = list[i]
        j = i - 1
        while j >= 0 and list[j] > key:

然后,使用 while 条件循环,判断前一位的元素是否比当前位的大,并且前一位的下标 >= 0(即最小到第一位)
这样就可以有条件的进行循环,而不像原来的写法那样一个个循环遍历。

def insertion_sort(list):
    n = len(list)
    for i in range(1, n):
        key = list[i]
        j = i - 1
        while j >= 0 and list[j] > key:
            list[j+1] = list[j]
            j -= 1
        list[j+1] = key
    return list

符合条件后,就可以把原来的元素位进行赋值操作,赋值成较大的元素;然后依次将较大的元素赋值给相比较的两位中的后面一位。直至比较到第一位或比较到某位元素小于当前元素的值。将保存起来的该位的值插入即可。

例:list = [1,4,5,3]
- 1循环 i 到第四位了 (i = 3)
- key保存 list[3] 的值,即 key = 3
- 然后将 list[2] 与 key = 3 比较,5>3,则将5的值赋给后面那位,即[1,4,5,5]
- 再将 list[1] 与 key = 3 比较 ,4>3,则将4的值赋给后面那位,即[1,4,4,5]
- 再将 list[0] 与 key = 3 比较 ,1<3,不符合循环条件
- 于是执行后面的语句,将 key = 3 值赋给 list[0+1] 即list[1],即[1,3,4,5]




补小知识点

range()函数

补个range()函数小知识点:

生成顺序的:

for i in range(1,10,1)
    print(i)

>> 1,2,3,4,5,6,7,8,9

生成倒序的:

for i in range(10,0,-1)
    print(i)

>> 10,9,8,7,6,5,4,3,2,1

因为 顾头不顾尾 ,所以生成的数减到 1 即停止了,不包括 0 。

& 和 and

优化后的代码,while 条件使用了两个条件与的判断
最初使用了 & 运算符,结果导致始终进不了循环,然后改为 and 即正常

运算符名称说明例子
&按位与数的按位与5&3 得1
and布尔“与”如果x为False,x and y返回False,否则它返回y的计算值x = False; y = True; x and y,由于x是False,返回False。在这里,Python不会计算y,因为它知道这个表达式的值肯定是False(因为x是False)。这个现象称为短路计算
  • 10
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值