1 插入排序

本文详细介绍了插入排序的算法核心思想,通过for和while两种方式解释具体实现逻辑,并对其时间复杂度进行了分析。讨论了插入排序的稳定性及其在实际工作中的意义,指出插入排序在元素部分有序或数量较少时效率较高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 算法核心思想

将数组中所有的元素分别和前面已经排序好的元素进行比较,如果后面的元素比已排序的元素小,则交换位置,直至比较完成。

2. 具体实现逻辑

2.1 for

arr = [1, 22, -1, 9, 23, 5]
将数组分成两部分:有序部分和无序部分
第一步:数组第一个元素为有序部分
有序部分[1]
无序部分[22, -1, 9, 23, 5]
第二步:取无序部分的第一个元素,与有序部分的元素作比较, 如果无序部分的元素小,则交换位置
有序部分[1, 22]
无序部分[-1, 9, 23, 5]
第三步:重复第二步
有序部分[-1, 1, 22]
无序部分[9, 23, 5]
第四步:重复第二步
有序部分[-1, 1, 9, 22]
无序部分[23, 5]
第五步:重复第二步
有序部分[-1, 1, 9, 22, 23]
无序部分[5]
第六步:重复第二步
有序部分[-1, 1, 5, 9, 22]
无序部分[]

def insertSort(arr):
    #默认数组第一个元素为有序部分,从第二个元素开始取
    for i in range(1,len(arr)):
        #arr[i]为无序部分元素
        #arr[:i]为有序部分
        #arr[i:]为有序部分
        for j in range(i,0,-1):
            if arr[j]<arr[j-1]:
                arr[j],arr[j-1] = arr[j-1],arr[j]
            else:
                break
    return arr

arr = [1, 22, -1, 9, 23, 5]
print(insertSort(arr))

2.2 while

首先用一个临时变量记录待插入的元素的值
temp=arr[i],然后比较
if temp<要比较的元素(来源于有序部分)
将要比较的元素往后挪,给temp腾位置
if temp>要比较的元素:break

def insertSortTwo(arr):
    for i in range(1,len(arr)):
        temp = arr[i]
        j = i-1
        while j>=0:
            if temp<arr[j]:
                arr[j+1] = arr[j]
                j -= 1
            else:
                break
        arr[j+1] = temp
    return arr

arr = [1, 22, -1, 9, 23, 5]
print(insertSortTwo(arr))

3. 时间复杂度分析

  1. 最好的情况,即序列已经是一个有序序列,每次比较内层循还执行一次就退出,则总的比较次数是n-1次,时间复杂度是O(n)
  2. 最坏的情况,即每次比较内层循环都要比较到第一个元素,则第一次循环比较了1次,第二次循环比较了2次…第n-1次循环比较了n-1次,则总的比较次数是n(n-1)/2,时间复杂度是O(n2)

4. 优缺点分析

  1. 在大多数元素已经有序的情况下,插入排序的工作量较小
  2. 在元素数量较少的情况下,插入排序的工作量较小,插入排序的工作量和n的平方成正比,如果n比较小,那么排序的工作量自然要小得多。
  3. 插入排序是一种稳定排序。

5. 插入排序的稳定性

相同的元素在排序后没有发生位置的变化,称为稳定性
相同的元素在排序后交换了位置,就是不稳定

6. 稳定性的意义

实际工作中,排序算法肯定不会根据数据的一个属性来排序
举例:双11,淘宝订单,按照付款金额和付款时间排序,交易金额的前100位送优惠券
如果有相同的付款金额,按照付款时间来决定
当按照付款金额排序好后,再按照付款时间排序时,不能将付款时间相同的两个订单交换位置,否则会改变付款金额的顺序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值