1.希尔排序介绍
希尔排序是插入排序的一种高效的改进版,并且效率比插入排序要更快.
1.希尔排序的历史背景:
- 希尔排序按其设计者希尔( Donald shel)的名字命名,该算法由1959年公布。
- 我们知道,优秀的排序算法首要条件就是速度.
- 在简单排序出现后的很多一段时间内,人们发明了各种各样的算法
- 但是最终发现算法的时间复杂度都是O(N2),似乎没法超越了.
- 此时,计算机学术界充斥着"排序算法不可能突破O(N)"的声音.
- 就像之前普遍认为人类100米短跑不可能突破10秒大关一样、
- 终于有一天,一位科学家发布超越了○(N)的新排序算法(后来为了纪念这个里程碑,用She‖来命名了该算法)
- 紧接着出现了好几种可以超越O(N2)的排序算法,我们后面将的快速排序也是其中之一
2.回顾插入排序
1.由于希尔排序基于插入排序所以有必须回顾一下前面的插入排序
2.我们设想一下,在插入排序执行到半的时候标记符左边这部分数据项都是排好序的,而标记符右边的数据项是没有
3.这个时候取出指向的那个数据项把它存储在一个临时变量中,接着,从刚刚移除的位置左边第—个单元开始,毎次把
4.有序的数据项向右移动一个单元直到存储在临时变量中的数据项可以成功插入.
插入排序的问题
1.假设一个很小的数据项在很靠近右端的位置上这里本来应该是较大的数据项的位置.
2.把这个小数据项移动到左边的正确位置,所有的中间数据项都必须向右移动一位
3.如果每个步骤对数据项都进行N次复制平均下来是移动N/2N个元素就是NN2=N2/2
4.所以我们通常认为插入排序的效率是O(N2)
5.如果有某种方式不需要—个个移动所有中间的数据项,就能把较小的数据项移动到左边, 那么这个算法的执行效率就会有很大的改进
2.希尔排序思路
3.选择合适的增量
4.代码实现
//4.希尔排序
ArrayList.prototype.shellSort = function() {
//1.获取长度
var length = this.array.length
//初始化间隔gap
var gap = Math.floor(length / 2)
//间隔循环到1时停止,用的是希尔的方法
while (gap >= 1) {
//分组插入
for (var i = gap; i < length; i++) {
//进行组内排序,利用插入排序
var j = i
var temp = this.array[i]
while (this.array[j - gap] > temp && j > gap - 1) {
this.array[j] = thi.array[j - gap]
j -= gap
}
this.array[j] = temp
}
gap = Math.floor(gap / 2)
}
}
5.效率分析
1.希尔排序的效率很增量是有关系的.
2.但是,它的效率证明非常困难,甚至某些増量的效率到目前依然没有被证明岀来.
3.但是经过统计,希尔排序使用原始增量最坏的情况下时间复杂度为N2),通常情况下都要好 于○(N2)
4.总之,我们使用希尔排序大多数情况下效率都高于简单排序,这个可以通过统计排序算法的时间来证明
5.甚至在合适的增量和某些数量N的情况下,还好好于快速排序.