排序——插入排序(Insertion sort)
算法思想
顾名思义,采用插入的方式,对无序数列进行排序。
维护一个有序区,将数据一个一个插入到有序区的适当位置,直到整个数组都有序。即每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
图示过程
初始状态
数列的初始值为。
先吧首元素 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)相关推荐
- python实现排序算法_python实现·十大排序算法之插入排序(Insertion Sort)
简介 插入排序(Insertion Sort)是一种简单直观的排序算法.它的工作原理是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法实现步骤 从第一个元素开 ...
- python sort 逆序_python实现·十大排序算法之插入排序(Insertion Sort)
简介 插入排序(Insertion Sort)是一种简单直观的排序算法.它的工作原理是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法实现步骤 从第一个元素开 ...
- [转载] python实现基本算法之插入排序(Insertion Sort)
参考链接: Python中的插入排序insertion sort 基本算法之插入排序(Insertion Sort) 基本算法-02.插入排序(Insertion Sort)算法 冒泡排序已经发布,大 ...
- 插入排序(Insertion Sort)-Java实现
插入排序(Insertion Sort)算法简介: 插入排序是一种丛序列左端开始依次对数据进行排序的算法.在排序过程中,左侧的数据陆续归位,而右侧留下的就是还未被排序的数据. 插入排序(Inserti ...
- C语言插入排序Insertion Sort算法(附完整源码)
插入排序Insertion Sort算法 插入排序Insertion Sort算法的完整源码(定义,实现,main函数测试) 插入排序Insertion Sort算法的完整源码(定义,实现,main函 ...
- C语言以递归实现插入排序Insertion Sort算法(附完整源码)
以递归实现插入排序Insertion Sort算法 以递归实现插入排序Insertion Sort算法的完整源码(定义,实现,main函数测试) 以递归实现插入排序Insertion Sort算法的完 ...
- 插入排序(Insertion Sort)
维基百科:http://zh.wikipedia.org/wiki/插入排序 算法思想: 若数组A[n]的前n-1个数已经有序,我们只需把第n个元素插入到适当的位置即可.易分析得算法的时间复杂度为Ο( ...
- 插入排序Insertion sort 2
原理类似桶排序,这里总是需要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数 例如 待排序数组[62,14,59,88,16]简单点五个数字 分 ...
- php代码编写直接插入排序算法,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析...
本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...
- 插入排序 php,PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析
本文实例讲述了PHP排序算法之直接插入排序(Straight Insertion Sort).分享给大家供大家参考,具体如下: 算法引入: 在这里我们依然使用<大话数据结构>里面的一个例子 ...
最新文章
- Android 导出traces.txt 遇到的坑
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATIBLE解决办法
- 虚拟机linux识别不了u盘_将Arch Linux安装到U盘
- Ubuntu下安装谷歌浏览器(Google chrome)报错
- 深度学习训练中关于数据处理方式--原始样本采集以及数据增广
- 【剑指offer】面试题40:最小的k个数(java)
- android app links,Android APP Links 配置
- 我的docker随笔11:Dockerfile编写
- 中国水稻种子行业市场供需与战略研究报告
- Brupsuit的安装与初步使用
- Zend_Db_Statement 一行无用代码
- IPv6套接字地址结构
- Python删除文件中含有特定值的行
- 乐高spike python_乐高教育EV3比SPIKE Prime更好的十个理由!
- 32位ubuntu 编译android源码,ubuntu 下编译android源码错误解决记录
- android 5.1一键root工具箱,最新的安卓5.1.1 ROOT教程(不需要刷第三方内核)
- Linux 桌面玩家指南:03. 针对 Gnome 3 的 Linux 桌面进行美化
- 背景色和背景图片共存,背景图片覆盖色
- 清华管理评论 | 上奇数科:产业知识服务引擎开创者
- netty 高匿ip检测_高匿代理ip不用担心被网站检测
热门文章
- 微信小程序开发步骤讲解和实用小技巧
- 约瑟夫问题java代码
- 计算机关机什么中的信息全部丢失,断电之后,信息全部丢失的是( )。A.RAMB.ROMC.软盘D.硬盘 - 作业在线问答...
- 在AI时代重新思考人机共生:理解人类在人机系统的最理想角色
- C语言sizeof与数组中的使用详解
- 价值240万的photoshop中文教程
- RK 7.1 reboot界面UI 风格 简单修改
- 提前写给自己的退役留念(无任何学习干货)
- vue中实现二维码登录功能
- 全球及中国天然气发电行业市场规模调研及未来前瞻报告2022-2028年