资讯专栏INFORMATION COLUMN

排序(2):直接插入排序

付伦 / 2817人阅读

摘要:一前言直接插入排序序是一种最简单的插入排序。所以,数据越接近正序,直接插入排序的算法性能越好。算法稳定性直接插入排序的过程中,不需要改变相等数值元素的位置,所以它是稳定的算法。

一、前言
直接插入排序(Insertion Sort)序是一种最简单的插入排序。为简化问题,我们下面只讨论升序排序。

二、算法思想
插入排序:每一趟将一个待排序的记录,按照其关键字的大小插入到有序队列的合适位置里,直到全部插入完成。

假设有一组无序序列 R0, R1, ... , RN-1。

(1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列。

(2) 然后,我们要依次把 R1, R2, ... , RN-1 插入到这个有序序列中。所以,我们需要一个外部循环,从下标 1 扫描到 N-1 。

(3) 接下来描述插入过程。假设这是要将 Ri 插入到前面有序的序列中。由前面所述,我们可知,插入Ri时,前 i-1 个数肯定已经是有序了。

所以我们需要将Ri 和R0 ~ Ri-1 进行比较,确定要插入的合适位置。这就需要一个内部循环,我们一般是从后往前比较,即从下标 i-1 开始向 0 进行扫描。

代码

# -*- coding:utf-8 -*-

def insertSort(input_list):
    if len(input_list) == 0:
        return []
    sorted_list = input_list

    for i in range(1, len(sorted_list)):
        temp = sorted_list[i]
        j = i - 1
        while j >=0 and temp < sorted_list[j]:
            sorted_list[j + 1] = sorted_list[j]
            j -= 1
        sorted_list[j + 1] = temp
    return sorted_list

if __name__ == "__main__":
    input_list = [6, 4, 8, 9, 2, 3, 1]
    print("排序前:", input_list)
    sorted_list = insertSort(input_list)
    print("排序后:", sorted_list)

三、算法分析
1、直接插入排序的算法性能

2、时间复杂度

当数据正序时,执行效率最好,每次插入都不用移动前面的元素,时间复杂度为O(N)

当数据反序时,执行效率最差,每次插入都要前面的元素后移,时间复杂度为O(N^2)

所以,数据越接近正序,直接插入排序的算法性能越好。

3、空间复杂度

由直接插入排序算法可知,我们在排序过程中,需要一个临时变量存储要插入的值,所以空间复杂度为 1 。

4、算法稳定性

直接插入排序的过程中,不需要改变相等数值元素的位置,所以它是稳定的算法。

四、优化

因为在一个有序序列中查找一个插入位置,以保证有序序列的序列不变,所以可以使用二分查找,减少元素比较次数提高效率。

二分查找是对于有序数组而言的,假设如果数组是升序排序的。那么,二分查找算法就是不断对数组进行对半分割,每次拿中间元素和目标数字进行比较,如果中间元素小于目标数字,则说明目标数字应该在右侧被分割的数组中,如果中间元素大于目标数字,则说明目标数字应该在左侧被分割的数组中。

代码

# -*- coding:utf-8 -*-

def BinarySearch(input_list, end, value):
    left = 0
    right = end - 1
    while left <= right:
        middle = left + (right - left) // 2
        if input_list[middle] >= value:
            right = middle - 1
        else:
            left = middle + 1

    return left if left < end else -1

def BinaryInsertSort(input_list):
    if len(input_list) == 0:
        return []
    result = input_list
    for i in range(1, len(input_list)):
        j = i - 1
        temp = result[i]
        insert_index = BinarySearch(result, i, result[i])
        if insert_index != -1:
            while j >= insert_index:
                result[j + 1] = result[j]
                j -= 1
            result[j + 1] = temp
    return result


if __name__ == "__main__":
    input_list = [6, 4, 8, 9, 2, 3, 1]
    print("排序前:", input_list)
    sorted_list = insertSort(input_list)
    print("排序后:", sorted_list)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43314.html

相关文章

  • JS中可能用得到的全部的排序算法

    本篇有7k+字, 系统梳理了js中常见的12种排序算法。除了基本排序算法,文章还包含了希尔排序、堆排序、桶排序等较为复杂的排序实现,如果喜欢请点赞支持~谢谢. 原文: http://louiszhai.github.io/20... 导读 排序算法可以称得上是我的盲点, 曾几何时当我知道Chrome的Array.prototype.sort使用了快速排序时, 我的内心是奔溃的(啥是快排, 我只知道...

    verano 评论0 收藏0
  • 【算法】插入排序——希尔排序+直接插入排序

    希尔排序 在介绍希尔排序之前,先了解一下直接插入排序 文章目录 希尔排序一、直接插入排序1. 单趟排序2. 直接插入排序 二、希尔排序三、测试希尔排序和直接插入排序性能 一、直接插入排序 1. 单趟排序 x插入一个有序区间 这里end是指向数组最后一个元素 2. 直接插入排序 根据上面的单趟排序启发 end是数组的最后一个元素,end之后的元素都是待排序 一个关键的判断点,end和...

    GitChat 评论0 收藏0
  • JavaScript 数据结构与算法之美 - 冒泡排序插入排序、选择排序

    摘要:之所以把冒泡排序选择排序插入排序放在一起比较,是因为它们的平均时间复杂度都为。其中,冒泡排序就是原地排序算法。所以冒泡排序是稳定的排序算法。选择排序思路选择排序算法的实现思路有点类似插入排序,也分已排序区间和未排序区间。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 1. 前言 算法为王。 想学好前端,先练好内功,...

    canger 评论0 收藏0
  • 【数据结构初阶】第九篇——八大经典排序算法总结(图解+动图演示+代码实现+八大排序比较)

    摘要:本篇博客我要来和大家一起聊一聊数据结构初阶中的最后一篇博客八大经典排序算法的总结,其中会介绍他们的原来,还有复杂度的分析以及各种优化。快速排序递归版本快速排序是于年提出的一种二叉树结构的交换排序方法。 ...

    xiaowugui666 评论0 收藏0

发表评论

0条评论

付伦

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<