基本算法學習(一)之希爾排序(JS)

參考書:
嚴蔚敏-數據結構javascript

希爾排序(Shell's Sort)

希爾排序又稱"縮小增量排序",歸屬於插入排序一類,簡單來講,和咱們的插入排序比,它更快.java

奇妙的記憶點:算法

  • 內排序(內存排序就夠了)數組

  • 不穩定(排序後原始順序沒法保證)數據結構

希爾排序重點在於分割.post

基本思想:

將整個待排序記錄序列分割爲若干個子序列,而後對每個子序列進行直接插入排序.學習

直接插入排序:

不得不先講一下直接插入排序了,畢竟希爾排序要使用到直接插入排序.
直接插入算法重點在於分區,有序區與無序區.假設咱們有一個數組arrspa

for(var i = 1;i<arr.length;i++){
    var key = arr[i];
    var j = i;
    while(j>0&&arr[j-1]>key){
        arr[j] = arr[j-1];
        j--;
    }
    arr[j]=key;
}

其中i=1,i~arr.len-1爲咱們的無序區,而i=0爲咱們的有序區.temp用於記錄無序區準備進入有序區的元素,j用於從右往左遍歷有序區並將元素日後推,找出相應的插入位置,將temp插入對應位置.code

希爾排序:代碼

希爾排序關鍵在於增量的設置,根據增量分割數組並逐步進行直接插入排序,增量逐趟減小,並最後使得整個數組基本有序,再對總體進行直接插入排序.blog

記憶點

  • best condition: T(n) = O(n*log2 n)

  • baddest condition: T(n) = O(n*log2 n)

  • average condition: T(n) = O(n*log n)

基本的思路就是根據增量分割數組,如var arr = [3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
咱們增量爲5,則分割爲
[3,15,46]
[44,36,4]
[38,26,19]
[5,27,50]
[47,2,48]
並對每一組進行直接插入排序
再把增量變爲2(減半),再進行分割,直到增量爲1,再對全體進行一次直接插入排序就能夠了.
簡略的代碼以下:

var len =arr.length;
    gap = Math.floor(len/2);
    while(gap!==0){
        for(var i = gap;i<len;i++){
            var temp = arr[i];
            var j;
            for(j=i-gap;j>=0&&temp<arr[j];j-=gap){
                arr[j+gap] = arr[j];
            }
            arr[j+gap] = temp;
        }
        gap=Math.floor(gap/2);
    }
  return arr;

簡單說一下,i從gap位開始,那麼每組的有序區已經肯定了一位,接下來將i-gap位的數根據組的不一樣插入有序區,就完成了每組的直接插入排序了.

相關流程圖

圖片描述

動態定義間隔序列

這是我在掘金看來的

希爾排序的核心在於間隔序列的設定。既能夠提早設定好間隔序列,也能夠動態的定義間隔序列。動態定義間隔序列的算法是《算法(第4版》的合著者Robert Sedgewick提出的。

while(gap < len/5) { //動態定義間隔序列 
    gap =gap*5+1; 
}

參考來源:http://gold.xitu.io/post/57dc...
詳細介紹了十種算法,你們能夠去學習下.

之後大概會盡可能天天更新一個算法學習吧,溫故而知新

相關文章
相關標籤/搜索