【手撕八大排序】——插入排序
创始人
2025-05-29 16:47:32
0

文章目录

  • 插入排序概念
  • 插入排序分为2种
    • 一 .直接插入排序
    • 直接插入排序时间复杂度
    • 二.希尔排序
  • 希尔排序时间复杂度
  • 效率比较


插入排序概念

直接插入排序是从一个有序的序列中选择一个合适的位置进行插入,这个合适的位置取决于是要升序排序还是降序排序。

每一次进行排序之后,这段数据都是有序的。


提示:以下是本篇文章正文内容,下面案例可供参考

插入排序分为2种

一 .直接插入排序

直接插入排序是从一段数据中将一个数据在合适的位置插入。

案例:
一张图弄懂直接插入排序
在这里插入图片描述
在这里插入图片描述

代码如下:

void InsertSort(int * a,int n )
{for(int i =0;iint end = i;//保存待插入元素int tmp = a[end+1];while(end>=0){if(a[end]>tmp){//把end往后挪a[end+1] = a[end];//end再往前走	end--;}else{break;}}//由于不管是在中间的任意地方插入还是在end的末尾插入(即tmp是最大的情况),//都是在end后面的位置插入,所以来到这里进行合并a[end+1] = tmp;}
}

直接插入排序时间复杂度

直接插入排序的时间复杂度为:O(N^2),因为最坏的情况是逆序的情况:
在这里插入图片描述

每一次插入需要挪动的次数为:1+2+3+4+…+n-2+n-1 = n*n/2

所以最坏情况下的时间复杂度为O(n^2)

二.希尔排序

希尔排序可以被认为是优化后的直接插入排序。

具体优化过程如下:

给定一个gap,这个gap是把待插入的数据分成gap组,每组之间的间隔为gap长度
给定一个gap,这个gap是把待插入的数据分成gap组,每组之间的间隔为gap长度
给定一个gap,这个gap是把待插入的数据分成gap组,每组之间的间隔为gap长度

重要的事情说三遍。

比如:

在这里插入图片描述
令gap = 3,即待插入的数据的间隔为3,不同于直接插入排序,直接插入排序是第一个和第二个数据的间隔永远为1,而对于希尔排序,当gap = 3时,第一个数据和第二个数据的间隔为3。
当我们把该组的元素两两比较时,大的元素就会更快地往后走。

在这里插入图片描述
第二轮是将待插入元素8和9比较,因为9后面的第一个元素不再是7,而是9+gap的位置处的数据,即8
再将9和8进行比较,将8插入到9位置处。

当然,这是每组组内的比较,

放眼整个希尔排序来说,是多组同时进行的

可以发现,
当gap越大,大的元素越快挪到后面
当gap越小,小的元素越慢挪到后面

当gap == 1时,就相当于上面提到的直接插入排序。

回到上面的案例,gap = 3,所以需要将数据分成3组,每组的间隔为3个长度。

在这里插入图片描述

如上图:此时每个元素都可以被覆盖到。

在这里插入图片描述

相当于同时把gap组中大的元素更快挪到后面

我们把上面的过程成为:预排序

也就是说,完成上面的操作之后,整个数据并不是有序的,而是 接近有序

比如上面的案例,完成预排序后,整组数据为:

在这里插入图片描述
此时是接近有序,所以此时令gap = 1,即最后接近有序的时候进行直接插入排序即可。

注意:gap的取值是不确定的:
gap取值越大,大的数据越快挪到后面,但越不接近有序
gap取值越小,大的数据越慢挪到后面,但越接近有序

总之gap是一定不能固定,并且gap的取值最后必须为1。

gap的取值应该是从大逐渐到小过渡的。

gap的取值一般是:

初始化gap = n,

进入轮回时:

gap = gap/3+1 或者 gap = gap/2,每次轮完一轮后,gap都会减小。

当gap的取值是gap = gap/2时,时间复杂度为:O(N*logN),logN是以2为底N的对数

最坏情况同样为逆序:

在这里插入图片描述
最后一轮gap = 1,此时为直接插入排序,则N/2/2/2/…/2 = 1,
每次轮回一次gap,gap都会/2,最后一次gap = 1,则需要比较的次数是logN(以2为底N的对数)

希尔排序时间复杂度

总的时间复杂度为遍历整组元素的次数:O(N)*每次遍历进行插入的次数O(logN)
—> O(N * logN)

同理:当gap的变化是gap = gap/3-1时, 最坏情况下(逆序)每次轮回需要插入的次数是

(((N/3+1) /3+1)/3+1)… = 1
对于时间复杂度:可忽略掉+1项,所以每次轮回插入次数log3 (N) ,以3为底N的对数

总时间复杂度为O(N*log3 (N))

经过前人计算,希尔排序平均时间复杂度为:
O(N^1.3)
在这里插入图片描述
实现代码:

void ShellSort(int* a, int n)
{//当gap越大,大的值越快到达最后的位置,但越不接近有序//当gap越小,大的值越慢到达最后的位置,但越接近有序//当gap值越接近1,排序越接近顺序//刚gap == 1时,就是直接插入排序int gap = n;while (gap > 1){//两种方式均可,gap可以任取任何值,但是都必须保证gap最后一定为1//gap = gap / 2;gap = gap / 3 + 1;//在这里就是把间隔多组的数据同时排列for (int i = 0; i < n - gap; i++){int end = i;int tmp = a[end + gap];while (end >= 0){//小于的情况,需要挪动数据if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}//大于或者等于的情况,直接插入end后面else{break;}}//由于最终都需要插入end后面,所以在循环之外插入a[end + gap] = tmp;}}
}

总结:希尔排序是在直接插入排序的基础上引入一个gap,这个gap把数据分成了gap组,并且每组元素之间的间隔也为gap。
gap每次都会逐渐减小,并且最后gap一定为1,当gap为1时,代表完成了预排序,
最后一步进行直接插入排序。


效率比较

void TestOP()
{srand(time(0));const int N = 1000000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);assert(a1 && a2);for (int i = 0; i < N; ++i){a1[i] = rand();a2[i] = a1[i];}//计算到这个走位置的时间(ms)int begin1 = clock();InsertSort(a1, N);int end1 = clock();//末位置-初位置就是时间差int begin2 = clock();ShellSort(a2, N);int end2 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);free(a1);free(a2);
}int main()
{TestOP();return 0;
}

在这里插入图片描述
可以看到,当排序数据为100w个时,直接插入排序和希尔排序差距超过了2000倍。

直接插入排序和希尔排序的效率相比,数据越多,希尔排序较于直接插入排序的优化越大。

相关内容

热门资讯

扫房神器2安卓系统,打造洁净家... 你有没有发现,家里的灰尘就像小精灵一样,总是悄悄地在你不注意的时候跳出来?别急,今天我要给你介绍一个...
安卓完整的系统设置,全面掌控手... 亲爱的手机控们,是不是觉得你的安卓手机用久了,功能越来越强大,但设置却越来越复杂?别急,今天就来带你...
电视安卓系统是几代机子,揭秘新... 你有没有想过,家里的电视是不是已经升级到了最新的安卓系统呢?别小看了这个小小的系统升级,它可是能让你...
安卓系统隐私有经常去,系统级防... 你知道吗?在咱们这个数字化时代,手机可是我们生活中不可或缺的好伙伴。但是,你知道吗?这个好伙伴有时候...
安卓10系统断网软件,轻松实现... 你有没有遇到过这种情况?手机突然断网了,明明信号满格,却连不上网,急得你团团转。别急,今天就来给你揭...
安卓可以改什么系统版本,体验全... 你有没有想过,你的安卓手机其实可以像换衣服一样,换一个全新的“系统版本”呢?没错,这就是今天我们要聊...
最好的平板游戏安卓系统,畅享指... 亲爱的游戏迷们,你是否在寻找一款能够让你在安卓平板上畅玩无忧的游戏神器?别急,今天我就要给你揭秘,究...
华为安卓系统卡顿解决,华为安卓... 你是不是也遇到了华为安卓系统卡顿的问题?别急,今天就来给你支几招,让你的华为手机重新焕发活力!一、清...
安卓建议升级鸿蒙系统吗,探讨鸿... 亲爱的安卓用户们,最近是不是被鸿蒙系统的新鲜劲儿给吸引了?是不是在犹豫要不要把你的安卓手机升级成鸿蒙...
安卓如何变苹果系统桌面,桌面系... 你有没有想过,把你的安卓手机变成苹果系统桌面,是不是瞬间高大上了呢?想象那流畅的动画效果,那简洁的界...
windows平板安卓系统升级... 你有没有发现,最近你的Windows平板电脑突然变得有些不一样了?没错,就是那个一直默默陪伴你的小家...
安卓系统扩大运行内存,解锁更大... 你知道吗?在科技飞速发展的今天,手机已经成为了我们生活中不可或缺的好伙伴。而手机中,安卓系统更是以其...
安卓系统怎么改变zenly,探... 你有没有发现,你的安卓手机上的Zenly应用最近好像变得不一样了?没错,安卓系统的大手笔更新,让Ze...
英特尔安卓子系统,引领高效移动... 你有没有想过,手机里的安卓系统竟然也能和电脑上的英特尔处理器完美结合呢?这可不是天方夜谭,而是科技发...
永远会用安卓系统的手机,探索安... 亲爱的手机控们,你是否也有那么一款手机,它陪伴你度过了无数个日夜,成为了你生活中不可或缺的一部分?没...
有哪些安卓手机系统好用,好用系... 你有没有发现,现在手机市场上安卓手机的品牌和型号真是琳琅满目,让人挑花了眼?不过别急,今天我就来给你...
卡片记账安卓系统有吗,便捷财务... 你有没有想过,用手机记账是不是比拿着小本本记录来得方便多了?现在,手机上的应用层出不穷,那么,有没有...
武汉摩尔影城安卓系统APP,便... 你有没有想过,一部手机就能带你走进电影的世界,享受大屏幕带来的震撼?今天,就让我带你详细了解武汉摩尔...
联想刷安卓p系统,畅享智能新体... 你有没有发现,最近联想的安卓P系统刷机热潮可是席卷了整个互联网圈呢!这不,我就迫不及待地来和你聊聊这...
mac从安卓系统改成双系统,双... 你有没有想过,你的Mac电脑从安卓系统改成双系统后,生活会有哪些翻天覆地的变化呢?想象一边是流畅的苹...