參考書:
嚴蔚敏-數據結構javascript
希爾排序又稱"縮小增量排序",歸屬於插入排序一類,簡單來講,和咱們的插入排序比,它更快.java
奇妙的記憶點:算法
內排序(內存排序就夠了)數組
不穩定(排序後原始順序沒法保證)數據結構
希爾排序重點在於分割.post
將整個待排序記錄序列分割爲若干個子序列,而後對每個子序列進行直接插入排序.學習
不得不先講一下直接插入排序了,畢竟希爾排序要使用到直接插入排序.
直接插入算法重點在於分區,有序區與無序區.假設咱們有一個數組arr
spa
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...
詳細介紹了十種算法,你們能夠去學習下.
之後大概會盡可能天天更新一個算法學習吧,溫故而知新