JS實(shí)現(xiàn)希爾排序

希爾排序本質(zhì)上是一種插入排序,但是對(duì)數(shù)列進(jìn)行了等間隔分組處理,在每一組中做插入排序,這一優(yōu)化使得原本 O(n^2) 的時(shí)間復(fù)雜度一下降為 O(nlogn)。

基本思想

希爾排序是按一定的間隔對(duì)數(shù)列進(jìn)行分組,然后在每一個(gè)分組中做插入排序;隨后逐次縮小間隔,在每一個(gè)分組中做插入排序...直到間隔等于1,做一次插入排序后結(jié)束。

那么問題來了,間隔應(yīng)該取多大,怎么縮?。客ǔN覀?nèi)ト〕跏奸g隔為數(shù)列長度的一半:gap = length/2,以 gap = gap/2 的方式縮小,下面詳細(xì)圖解整個(gè)過程。

原始數(shù)組數(shù)組如下:


首先取間隔為 gap = length/2 = 4,將數(shù)組分為如下的4組,對(duì)每一組實(shí)施插入排序:


第一次排序,每一組較小的元素都移到了相對(duì)靠前的位置(這個(gè)狀態(tài)可以叫 n-sorted,即以n為gap分組有序),可以想象相對(duì)有序的數(shù)組可能更有利于后面的排序。接著繼續(xù)分組,gap = gap/2 = 2,對(duì)每一組實(shí)施插入排序:


繼續(xù)對(duì)數(shù)組分組,gap = gap/2 = 1,即所有元素組成一組,做插入排序完成算法:

代碼實(shí)現(xiàn)

內(nèi)層循環(huán)使用的插入排序與普通的插入排序基本一致,只是每次移動(dòng)的步長變?yōu)?gap 而不是 1:

// shellSort
function shellSort(arr) {
  for(let gap = Math.floor(arr.length/2); gap > 0; gap = Math.floor(gap/2)) {
    // 內(nèi)層循環(huán)與插入排序的寫法基本一致,只是每次移動(dòng)的步長變?yōu)?gap
    for(let i = gap; i < arr.length; i++) {
      let j = i;
      let temp = arr[j];
      for(; j> 0; j -= gap) {
        if(temp >= arr[j-gap]) {
          break;
        }
        arr[j] = arr[j-gap];
      }
      arr[j] = temp;
    }
  }
  return arr;
}

// example
let arr = [2,5,10,7,10,32,90,9,11,1,0,10];
alert(shellSort(arr));
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容