首页 > 代码库 > 插入排序---希尔插入排序算法(Javascript版)

插入排序---希尔插入排序算法(Javascript版)

取一个小于n的整数作为第一个增量,把序列分组。所有距离为增量的倍数的元素放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量(第二个<第一个)重复上述的分组和排序,直至所取的增量=1,即所有元素放在同一组中进行直接插入排序为止。

 

一般的初次取序列的一半为增量,以后每次减半,直到增量为1。

 

以下代码在nodejs中执行通过。

function shellInsertSort(elements, di){  //从增量的所在位置开始  for(var i = di; i < elements.length; i++){    //升序    if(elements[i] < elements[i-di]){      //取出增量位置的元素作为被插入元素(哨兵)      var guard = elements[i];      var j = i - di;      elements[i] = elements[j];            //向前,将增量的倍数的位置作为同一组比较及进行直接插入法      while(j >= 0 && guard < elements[j]){        elements[j+di] = elements[j];        j -= di;      }            //插入      elements[j + di] = guard;    }  }}function shellSort(elements){  //增量为序列的一半  var di = parseInt(elements.length / 2);  while(di >= 1){    shellInsertSort(elements, di);    //每次减半,最后增量必须为1    di = parseInt(di / 2);  }}var elements = [10, 9, 8, 7, 6, 5];console.log(‘before: ‘ + elements);shellSort(elements);console.log(‘ after: ‘ + elements);

 

效率:比直接插入法快。但不是一种稳定的排序算法,关键取决于增量的选择,初次通常选取序列长度的一半。

(转帖):希尔排序时间复杂度的下界是n*log2n。希尔排序没有快速排序算法快 O(n(logn)),因此中等大小规模表现良好,对规模非常大的数据排序不是最优选择。但是比O(n^2)复杂度的算法快得多。并且希尔排序非常容易实现,算法代码短而简单。 此外,希尔算法在最坏的情况下和平均情况下执行效率相差不是很多,与此同时快速排序在最坏的情况下执行的效率会非常差。专家们提倡,几乎任何排序工作在开始时都可以用希尔排序,若在实际使用中证明它不够快,再改成快速排序这样更高级的排序算法. 本质上讲,希尔排序算法是直接插入排序算法的一种改进,减少了其复制的次数,速度要快很多。 原因是,当n值很大时数据项每一趟排序需要的个数很少,但数据项的距离很长。当n值减小时每一趟需要和动的数据增多,此时已经接近于它们排序后的最终位置。 正是这两种情况的结合才使希尔排序效率比插入排序高很多。
在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。

 

插入排序---希尔插入排序算法(Javascript版)