算法思想

顾名思义,采用插入的方式,对无序数列进行排序。

维护一个有序区,将数据一个一个插入到有序区的适当位置,直到整个数组都有序。即每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

图示过程

初始状态

数列的初始值为

先吧首元素 5 作为有序区,此时有序区只有一个元素,如下图所示。

第一轮

将下一个元素 8 和有序区所有元素依次比较,找到合适的位置,然后插入。

,所以元素 8 和元素 5 不需要交换。这样有序区的元素增加到两个,如下图所示。

第二轮

将下一个元素 6 和有序区所有元素依次比较,找到合适的位置,然后插入。

,所以元素 6 和元素 8 进行交换,如下图所示。

再比较 6 和 5 ,,所以元素 6 和元素 5 不需要交换。这样有序区的元素增加到三个,如下图所示。

第三轮

将下一个元素 3 和有序区所有元素依次比较,找到合适的位置,然后插入。

,所以元素 3 和元素 8 进行交换,如下图所示。

,所以元素 3 和元素 6 进行交换,如下图所示。

,所以元素 3 和元素 5 进行交换,如下图所示。

这样有序区的元素增加到四个,如下图所示。

......

依次类推,直到整个数列的元素插入完毕,排序完成。

整个插入排序过程

下图是每一轮插入排序的结果。

说明:上述的排序过程没有记性优化,相关的优化可以参考下面的内容。

算法优化

注意:插入排序的算法优化不会降低算法的时间复杂度,只是减少了许多无谓的交换

我们观察一下第三轮操作中,发现需要让元素 3 逐个与有序区的元素进行比较和交换,整个交换过程是:与 8 交换、与 6 交换、与 5 交换,最终交换到有序区的第一个位置。可以发现,并不需要进行着三次交换,算法可以进行优化。

只需要把元素 3 暂时保存起来,先把有序区的元素从左到右逐一复制,再将元素 3 插入到合适的位置即可。具体过程用图示说明。

第一步

暂存元素 3 ,入下图所示。

第二步

和前一个元素比较,由于 3 < 8,复制元素 8 到它下一个位置。如下图所示。

第三步

和前一个元素比较,由于 3 < 6,复制元素 6 到它下一个位置。如下图所示。

第四步

和前一个元素比较,由于 3 < 5,复制元素 5 到它下一个位置。如下图所示。

第五步

到达有序区的第一位,比较完成。将暂存的元素 3 赋值到数组的首位。如下图所示。

结论

显然,这样的优化减少了许多无谓的交换过程。

动图展示

算法性能

关键字比较次数记为C,记录移动次数记为M。

时间复杂度

1、当初始序列为正序时,只需要外循环 n-1 次,每次进行一次比较,无需移动元素。此时比较次数 和移动次数  达到最小。

,此时时间复杂度为

2、当初始序列为反序时,需要外循环 n-1 次,每次排序中待插入的元素都要和 [0, i-1] 中的 i 个元素进行比较且要将这 i 个元素后移 i 次,加上 tmp = arr[i] 与 arr[j] = temp 的两次移动,每趟移动次数为 i+2,此时比较次数和移动次数达到最大值。

此时时间复杂度为

空间复杂度

在直接插入排序中,需要了三个辅助变量,与数据规模无关,空间复杂度为

稳定性

稳定排序算法。因为相同元素的相对位置不变,如果两个元素相同,插入元素放在相同元素后面。

代码实现

C和C++

void insertionSort(int array[], int len) {if (len<2) {return 0;}for (int i=1; i<len; i++) {int insertValue = array[i];//暂存需要插入元素int j = i-1;//从右向左比较元素for (; j>=0 && insertValue<array[j]; j--) {array[j+1] = array[j];}array[j+1] = insertValue;}
}

Java

public static void insertionSort(int[] array) {if (null==array || 1==array.length) {return;}for (int i=1; i<array.length; i++) {int insertValue = array[i];//暂存需要插入元素int j = i-1;//从右向左比较元素for (; j>=0 && insertValue<array[j]; j--) {array[j+1] = array[j];}array[j+1] = insertValue;}
}

Python

def InsertionSort(arr):n = len(arr)for i in range(1,n):        temp = arr[i]# j保存元素temp应该插入的位置for j in range(i,-1,-1):if arr[j-1]>temp and j>0:arr[j] = arr[j-1]  # 后移即可else:breakarr[j] = temp

进一步优化

插入排序标准算法在有序区查找合适位置时,采用从左到右逐一查找的方法。

我们可以采用二分查找的方法来进一步优化。

排序——插入排序(Insertion sort)相关推荐

  1. python实现排序算法_python实现·十大排序算法之插入排序(Insertion Sort)

    简介 插入排序(Insertion Sort)是一种简单直观的排序算法.它的工作原理是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法实现步骤 从第一个元素开 ...

  2. python sort 逆序_python实现·十大排序算法之插入排序(Insertion Sort)

    简介 插入排序(Insertion Sort)是一种简单直观的排序算法.它的工作原理是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法实现步骤 从第一个元素开 ...

  3. [转载] python实现基本算法之插入排序(Insertion Sort)

    参考链接: Python中的插入排序insertion sort 基本算法之插入排序(Insertion Sort) 基本算法-02.插入排序(Insertion Sort)算法 冒泡排序已经发布,大 ...

  4. 插入排序(Insertion Sort)-Java实现

    插入排序(Insertion Sort)算法简介: 插入排序是一种丛序列左端开始依次对数据进行排序的算法.在排序过程中,左侧的数据陆续归位,而右侧留下的就是还未被排序的数据. 插入排序(Inserti ...

  5. C语言插入排序Insertion Sort算法(附完整源码)

    插入排序Insertion Sort算法 插入排序Insertion Sort算法的完整源码(定义,实现,main函数测试) 插入排序Insertion Sort算法的完整源码(定义,实现,main函 ...

  6. C语言以递归实现插入排序Insertion Sort算法(附完整源码)

    以递归实现插入排序Insertion Sort算法 以递归实现插入排序Insertion Sort算法的完整源码(定义,实现,main函数测试) 以递归实现插入排序Insertion Sort算法的完 ...

  7. 插入排序(Insertion Sort)

    维基百科:http://zh.wikipedia.org/wiki/插入排序 算法思想: 若数组A[n]的前n-1个数已经有序,我们只需把第n个元素插入到适当的位置即可.易分析得算法的时间复杂度为Ο( ...

  8. 插入排序Insertion sort 2

    原理类似桶排序,这里总是需要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数 例如 待排序数组[62,14,59,88,16]简单点五个数字 分 ...

  9. php代码编写直接插入排序算法,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析...

    本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...

  10. 插入排序 php,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析

    本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...

最新文章

  1. Android 导出traces.txt 遇到的坑
  2. 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
  3. 虚拟机linux识别不了u盘_将Arch Linux安装到U盘
  4. Ubuntu下安装谷歌浏览器(Google chrome)报错
  5. 深度学习训练中关于数据处理方式--原始样本采集以及数据增广
  6. 【剑指offer】面试题40:最小的k个数(java)
  7. android app links,Android APP Links 配置
  8. 我的docker随笔11:Dockerfile编写
  9. 中国水稻种子行业市场供需与战略研究报告
  10. Brupsuit的安装与初步使用
  11. Zend_Db_Statement 一行无用代码
  12. IPv6套接字地址结构
  13. Python删除文件中含有特定值的行
  14. 乐高spike python_乐高教育EV3比SPIKE Prime更好的十个理由!
  15. 32位ubuntu 编译android源码,ubuntu 下编译android源码错误解决记录
  16. android 5.1一键root工具箱,最新的安卓5.1.1 ROOT教程(不需要刷第三方内核)
  17. Linux 桌面玩家指南:03. 针对 Gnome 3 的 Linux 桌面进行美化
  18. 背景色和背景图片共存,背景图片覆盖色
  19. 清华管理评论 | 上奇数科:产业知识服务引擎开创者
  20. netty 高匿ip检测_高匿代理ip不用担心被网站检测

热门文章

  1. 微信小程序开发步骤讲解和实用小技巧
  2. 约瑟夫问题java代码
  3. 计算机关机什么中的信息全部丢失,断电之后,信息全部丢失的是( )。A.RAMB.ROMC.软盘D.硬盘 - 作业在线问答...
  4. 在AI时代重新思考人机共生:理解人类在人机系统的最理想角色
  5. C语言sizeof与数组中的使用详解
  6. 价值240万的photoshop中文教程
  7. RK 7.1 reboot界面UI 风格 简单修改
  8. 提前写给自己的退役留念(无任何学习干货)
  9. vue中实现二维码登录功能
  10. 全球及中国天然气发电行业市场规模调研及未来前瞻报告2022-2028年