插入排序,希尔排序原理,代码及复杂度分析
插入排序算法
算法原理:
* 插入排序原理很简单,讲一组数据分成两组,
* 我分别将其称为有序组与待插入组。
* 每次从待插入组中取出一个元素,与有序组的元素进行比较,并找到合适的位置,
* 将该元素插到有序组当中。就这样,每次插入一个元素,有序组增加,待插入组减少。
* 直到待插入组元素个数为0。
* 当然,插入过程中涉及到了元素的移动。
*/
例如:45 80 48 40 22 78
第一轮:45 80 48 40 22 78 ---> 45 80 48 40 22 78 i=1
第二轮:45 80 48 40 22 78 ---> 45 48 80 40 22 78 i=2
第三轮:45 48 80 40 22 78 ---> 40 45 48 80 22 78 i=3
第四轮:40 45 48 80 22 78 ---> 22 40 45 48 80 78 i=4
第五轮:22 40 45 48 80 78 ---> 22 40 45 48 78 80 i=5
图解:(图片来自网络 侵权删除)
实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public void InsertSort( int arr[]){ int i,j,temp; for (i= 1 ;i<arr.length;i++){ //从第二个元素开始,第一个默认为有序的 temp=arr[i]; //准备排序的那个元素 j=i- 1 ; //排好序的数列的最后一个元素 while (j>= 0 &&temp<arr[j]){ //j>=0表示插入的边界, arr[j+ 1 ]=arr[j]; //排序数列后移一个序列 j--; } arr[j+ 1 ]=temp; } } |
时间复杂度:
最好情况(原本就是有序的)
比较次数:Cmin=n-1
移动次数:Mmin=0
最差情况(逆序)
比较次数:Cmax=2+3+4+……+n=(n+2)n/2
移动次数:Mmax=1+2+3+……+n-1=n*n/2
故时间复杂度为o(n^2)
希尔排序
算法原理:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量 =1(
<
…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
图解(图片来自网络,侵权删除)
实现代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public void shellSort( int arr[]){ int i,j,temp,len; len=arr.length; for ( int step=len/ 2 ;step> 0 ;step=step/ 2 ){ //最外外层循环,根据步长分组 // for (step = len / 2; step > 0; step /= 2) for (i= 0 ;i<step;i++){ //用直接插入法对每一组进行排序 for (j=i+step;j<len;j=j+step){ if (arr[j]<arr[j-step]){ temp=arr[j]; int k=j-step; //已经排序的最后一个元素的下标 while (k>= 0 &&arr[k]>temp){ arr[k+step]=arr[k]; //排序序列右移步长个序列 k=k-step; //找前一个元素 } arr[k+step]=temp; //找到合适的位置 则直接插入 } } } } } |
希尔排序的时间复杂度:
平均时间复杂度:希尔排序的时间复杂度和其增量序列有关系,这涉及到数学上尚未解决的难题;不过在某些序列中复杂度可以为O(n1.3);
排序方法 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 | 复杂性 |
---|---|---|---|---|---|---|
直接插入排序 | n2 O(n2) |
O(n2) |
O(n) | O(1) |
稳定 | 简单 |
希尔排序 | O(nlog2n) |
n2 O(n2) |
O(n) | O(1) | 不稳定 | 较复杂 |
总结:
-
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
-
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!