JS實現希爾排序

希爾排序本質上是一種插入排序,可是對數列進行了等間隔分組處理,在每一組中作插入排序,這一優化使得時間複雜度降到了O(n^2)如下。算法

基本思想

希爾排序是按必定的間隔對數列進行分組,而後在每個分組中作插入排序;隨後逐次縮小間隔,在每個分組中作插入排序...直到間隔等於1,作一次插入排序後結束。shell

那麼問題來了,間隔應該取多大,怎麼縮小?一般咱們去取初始間隔爲數列長度的一半:gap = length/2,以 gap = gap/2 的方式縮小,下面詳細圖解整個過程。數組

原始數組數組以下:優化

clipboard.png


首先取間隔爲 gap = length/2 = 4,將數組分爲以下的4組,對每一組實施插入排序:spa

clipboard.png


第一次排序,每一組較小的元素都移到了相對靠前的位置(這個狀態能夠叫 n-sorted,即以n爲gap分組有序),能夠想象相對有序的數組可能更有利於後面的排序。接着繼續分組,gap = gap/2 = 2,對每一組實施插入排序:3d

clipboard.png


繼續對數組分組,gap = gap/2 = 1,即全部元素組成一組,作插入排序完成算法:code

clipboard.png

clipboard.png

代碼實現

內層循環使用的插入排序與普通的插入排序基本一致,只是每次移動的步長變爲 gap 而不是 1:blog

// shellSort
function shellSort(arr) {
  for(let gap = Math.floor(arr.length/2); gap > 0; gap = Math.floor(gap/2)) {
    // 內層循環與插入排序的寫法基本一致,只是每次移動的步長變爲 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));
相關文章
相關標籤/搜索