Python-插入排序

1、直接插入排序流程图

插入排序:每一趟都要把待排序数放到有序区中合适的插入位置

2、核心算法

结果可为升序或降序排列,默认升序排列。以升序为例
扩大有序区,减小无序区。图中绿色部分就是增大的有序区,黑色部分就是减小的无序区
增加一个哨兵位,图中最左端红色数字,其中放置每一趟待比较数值
将哨兵位数值与有序区数值从右到左依次比较,找到哨兵位数值合适的插入点

3、算法实现

3.1、增加哨兵位

为了方便,采用列表头部索引0位置插入哨兵位
每一次从有序区最右端后的下一个数,即无序区最左端的数放到哨兵位

3.2、比较与挪动

从有序区最右端开始,从右至左依次与哨兵比较
比较数比哨兵大,则右移一下,换下一个左边的比较数
直到找到不大于哨兵的比较数,这是把哨兵插入到这个数右侧的空位即可

3.3、代码示例

m_list = [
    [1, 9, 8, 5, 6, 7, 4, 3, 2],
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [9, 8, 7, 6, 5, 4, 3, 2, 1]
]
nums = [0] + m_list[0]
print(nums[1:])
length = len(nums)
count_move = 0
for i in range(2, length):  # 测试的值从nums的索引2开始向后直到最后一个元素
    nums[0] = nums[i]  # 索引0位哨兵,索引1位假设的有序区,都跳过
    j = i - 1  # i左边的那个数就是有序区末尾
    if nums[j] > nums[0]:  # 如果最右侧数大于哨兵才需要挪动和插入
        while nums[j] > nums[0]:
            nums[j + 1] = nums[j]  # 右移,不是交换
            j -= 1  # 继续向左
            count_move += 1
            nums[j + 1] = nums[0]  # 循环中多减了一次j
print(nums[1:])

4、总结

最好情况,正好是升序排列,比较迭代n-1次
最差情况,正好是降序排列,比较迭代1,2,...,n-1即 n(n-1)/2,数据移动非常多
使用两层嵌套循环,时间复杂度O(n^2)
稳定排序算法 如果待排序序列R中两元素相等,即Ri等于Rj,且i
< j ,那么排序后这个先后顺序不变,这种 排序算法就称为稳定排序
使用在小规模数据比较
优化 如果比较操作耗时大的话,可以采用二分查找来提高效率,即二分查找插入排序

5、排序稳定性

冒泡排序,相同数据不交换,稳定
直接选择排序,相同数据前面的先选择到,排到有序区,不稳定
直接插入排序,相同数据不移动,相对位置不变,稳定
posted @ 2023-07-05 15:28  小粉优化大师  阅读(363)  评论(0)    收藏  举报