排序系列插入 / 希尔
本文介绍插入排序和希尔排序,插入排序是较为常见的排序算法,希尔排序也是基础的排序算法,废话不多说,具体来看一下两种算法。
插入排序
插入排序的基本思想是拿到下一个插入元素,在已经有序的待排数组部分找到自己的位置,然后进行数据的移动,完成该元素的排序,依次类推,直到整个待排数组有序,初始状态待排数组的有序部分仅有一个元素。代码如下:
上面这种方式两两数据交换,换到合适位置,每次交换多了两次赋值操作,下面是实现的标准模式:
以上就是插入排序的两种实现方式,并没有改进,其时间复杂度为O(n^2),妥妥的两层循环,另外插入排序是稳定排序,存不存在一种改进的插入排序呢?答案是有的,这就是我们下面要介绍的希尔排序;
希尔排序
希尔排序是插入排序的改进版。主要改进思路是减少插入排序中数据的移动次数,设置步长,在初始数组较大时取较大步长,通常初始步长为待排数组长度1/2,此时只有两个元素比较,交换一次,此时数组为部分有序数组;之后步长依次减半直至步长为1,即为插入排序,此时数组已接近有序,所以插入元素时数据移动次数会相对较少,效率得到提高,实现代码如下:
既然为改进算法,那么相比较插入排序,希尔排序的到底快了多少呢?为此特意去找了资料,一般书上都说希尔排序的时间复杂度是O(n^3/2),但是学过算法的都知道有最坏时间复杂度的,希尔排序的时间复杂度其实是和增列序列有关系的,即我们程序实现的步长,{1,2,4,8,...}这种序列就是我们程序中实现的这种,并不是很好的增量序列,使用这个增量序列的时间复杂度(最坏情形)是O(n^2),Hibbard
提出了另一个增量序列{1,3,7,...,2^k-1}(质数增量),这种序列的时间复杂度(最坏情形)为O(n^1.5),这个提高就很厉害了,只是修改一个算法的一个参数;Sedgewick
提出了几种增量序列,其最坏情形运行时间为O(n^1.3),其中最好的一个序列是{1,5,19,41,109,...},最后这个就当是科普小知识吧,因为给你你也不一定能用,请原谅我的直接,当别人说希尔排序的最坏时间复杂度是O(n^2)的时候,你也可以给他们科普一下,希尔排序的最坏时间复杂度是可以做到O(n^1.3)的。
总结
插入排序感觉是最为直观的排序方式,如果有人没有学过算法,人们最直接的排序方式就是,一个一个去找数字的位置,确定,然后再去找下一个,所以思想很简单,但是我们看到即时这样简单地排序思想,到了希尔这里,也能玩出花,所以对任何东西,尤其是简单的事物,都要心怀敬畏啊。
构成我们学习最大障碍的是已知的东西,而不是未知的东西。——贝尔纳
版权声明: 本文为 InfoQ 作者【脚动两轮男之漂流小王子】的原创文章。
原文链接:【http://xie.infoq.cn/article/cdb08c5f983243c3a8ae0a6ff】。文章转载请联系作者。
评论