上一篇文章我们一起学习了直接插入排序,它的原理就是把前i个长度的序列变成有序序列,然后循环迭代,直至整个序列都变为有序的.但是说来说去它还是一个时间复杂度为(n^2)的算法,难道就不能再进一步把时间复杂度降低一阶么?可能有很多同学说快速排序,堆排序,我都会,这些简单的插入排序我都不屑于用.确实,以上几种算法相对于之前的O(n^2)级别的算法真的是弱爆了,效率可能还会差上千万倍,但是我们不妨翻看一下历史,你就会感觉每一种算法的出现都是很可贵的.
在1959年D.L.Shell正式提出了我们今天的主角shell算法,这是相当酷的一件事情,为什么这么说呢?因为shell排序时第一个突破了O(n^2)时间复杂度的排序算法,这应该是排序算法历史上比较闪耀的时刻了,因为在1959年之前的相当长的一段时间里,各种各样的排序算法无论是怎么花样繁多,都始终无法突破O(n^2)雷池一步,在当时直接插入排序已经是相当优秀的了,而排序算法不可能突破O(n^2)的声音成为了当时的主流.
看见了这段历史之后你有什么感受呢,我们在课堂上不愿意学的算法确仍然是科学家们多年苦苦思索才发明出来的,是不是觉得他们很不容易呢?其实你也没必要内疚啦,即使你曾经对它不屑一顾过,没有认真的学它,So what?现在开始学也不晚是不是?
- 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
- 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
shell算法的核心还是分组,但是这个分组就有门道儿了,因为它会实现取一个小于总数据长度的整数值gap作为分组的步长,什么意思呢?假如我们的待排序数组为:
序号 1 2 3 4 5 6 7 8 9 10
49,38,65,97