全栈工程师开发手册 (作者:栾鹏)

​​ js系列教程5-数据结构和算法全解​​

js排序算法详解-希尔排序

希尔排序,直接上图;

js排序算法详解-希尔排序_排序

像这个算法看图理解起来并不是很难,就像比赛一样,1-6一组,2-7一组,每差5为一组进行比较,之后再每差2为一组进行比较,最后就是两两比较,有点类似冒泡算法,但又比冒泡多了一层增量的概念。起初小编看到这个导图的时候感觉编程挺简单的,无非就是改变一下增量,这有何难?人呐,都是眼高手低,废话不多说直接看代码:

function shellSort(arr) {
  var len = arr.length,
  temp,
  gap = 1;
  console.time('希尔排序耗时:');
  while(gap < len/5) { //动态定义间隔序列
    gap =gap*5+1;
  }
  for (gap; gap > 0; gap = Math.floor(gap/5)) {
    for (var i = gap; i < len; i++) {
      temp = arr[i];
      for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) {
        arr[j+gap] = arr[j];
      }
      arr[j+gap] = temp;
    }
  }
  console.timeEnd('希尔排序耗时:');
  return arr;
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(shellSort(arr));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50];

当读到while循环时,我类个去,什么鬼?什么意思?再往下读,好了,放弃吧!看起来云里雾里,变量附来附去,什么意思?

抽象看不明白那就实例化,以arr为例代进去一看究竟,len/5 以五步为增量,这好像是说的通,但是gap = gap *5 +1 ;这是什么鬼?

别着急慢慢读,len = 15 ,gap = 6 ;while循环结束。再往下读,var i = gap ;也就是说从i = 6开始循环一直到数组末尾,然后从i=6开始记录元素,而对于下标为 j 的for循环,则是从0开始,然后以步长为6开始比较,接下来就会发现一个问题,j-=gap ? 又是什么鬼? j=0,j-=gap ,那 j 不就是负的了么?编者这么写是有他的理由的,对,在下标为6之前的元素之循环了一次,那下边如果超过6呢,所以小编觉得这个地方也算是个亮点吧!

还没结束,这层内层循环结束了,跳了出来,gap = Math.floor(gap/5) 又是什么玩意?只是常规的思想局限了创新,这个不就是与while循环的gap = gap 5+1 ;与之相应么?这么做有什么好处呢,也就是说无论数据有多大,最终肯定会走到每隔6步为已增量的循环中,这就是希尔排序的亮点所在,而且前面定义的gap=1;还有gap = gap5+1 ;这个1不是随便定义的,因为最终回归到的就是增量为1的循环当中!