說起查詢演算法,二分查詢是肯定不能少的,當然鵝廠有些猿喜歡叫他歐巴馬查詢~二分查詢的時間複雜度為o(logn),不線性查詢的時間複雜度o(n)更優秀。
核心思想:
是將n個元素分成大致相等的兩部分,取a[n/2]與x做比較,如果x=a[n/2],則找到x,演算法中止;如果x
function binary(arr, key) else
if (arr[middle] < key) else
}return -1;
}var arr = [1, 2,4, 6];
console.log(binary(arr, 1))
上面一段**簡單清晰,我相信大家稍微理解下就明白了。很顯然,這個查詢不夠優化,每次都從中間查起。對偏於邊緣的數很不公平,很多時候100以內的數都要查詢7次。此時我想起了幾何的相似三角形。a / a +b = c / c + d;如果我把待查詢的數字放到對應的查詢元素中,不也可以通過數軸構成相似三角形麼。這就是我下面要分享的插入二分查詢,它和二分查詢只有一點區別,二分查詢找的是中間值,插入二分查詢找的是插入值。
二分查詢中間值為:
middle = (high + low) /2 , 改造一下變成middle = low + (high - low) /2 這裡就是改造一下(high - low) / 2。我們結合當前元素在數軸中的比值。當前元素為value,查詢陣列為arr,則:
(value - arr[low] )/(arr[high] -arr [low]) * (high - low) + low 這是不是更接近於當前元素在待查詢陣列中的位置。
現在就讓我來將二分查詢稍微改造下:
function binary(arr, key) else
if (arr[middle] < key) else
}return -1;
}var arr = [1, 2,4, 6];
console.log(binary(arr, 3))
和二分查詢相比,只是修改了一下獲取中值的方式。整體思想和二分查詢是一樣的,經過這樣一改造,每次查詢都更接近待查詢的元素,這裡有一點需要特別注意 middle = math.round()這裡不能用parseint,不然極可能出現死迴圈。
這裡還有一種優化二分查詢中值的方法,叫斐波那契查詢。由於斐波那契值越大,最後乙個元素與倒數第二個元素的比值越接近0.618這個**分割比值。所以這種查詢法也叫**分割查詢。先實現乙個斐波那契數列:
function
fibogenerator
(n)
return arr;
}
現在關鍵是如何選擇生成多大的斐波那契數列。現在大多數的實現是選擇長度為20的斐波那契數列,額這個我也不多做評價,我也這樣選^_^。如果這個長度還不夠,那就手動調整吧~總體**如下:
function
fibogenerator
(n)
return arr;
}const max_fibo_length = 20;
function
insert
(arr, key)
for (let i = arr.length - 1; i < f[k] - 1; i ++)
while (low <= high) else
if (arr[middle] < key) else
}return -1;
}
var arr = [1, 3, 4, 5, 6];
console.log(insert(arr, 2));
以上就是二分查詢和主流的優化方式,個人覺得還是插入二分查詢最靠譜,最高效,並且插入二分查詢理解起來簡單,用起來方便,所以強烈推薦插入二分查詢。這篇文章很長,如果你能看到這裡還沒關掉,那我就強烈給你推薦一本書《大話資料結構》,很不錯的,thx~ 對資料結構和演算法的總結和思考(一) 概覽
前段時間陸續看了各種排序演算法和查詢演算法,覺得不過癮,很多東西不系統,所以網上找了一本書程杰的 大話資料結構 這段時間認真學習了全本內容,收穫頗多,想著就總結一下這段時間所學,所思,權當給大家乙個借鑑吧。先從排序演算法說起現在流行的排序演算法如果按型別分大致分為五大類 選擇排序類 插入排序類 交換...
對資料結構和演算法的總結和思考(三) 希爾排序
希爾排序是第乙個時間複雜度突破o n 2 的高階演算法。顧名思義,這就是被希爾發現的一種排序演算法。演算法本質為分組插入排序。具體實現為 let count 0 function shellsort arr for gap gap 0 gap math.floor gap times arr fla...
對資料結構和演算法的總結和思考(五) 堆排序
本篇分享的內容為堆排序,提到堆排序就不得不提一下堆這個資料結構。堆實際上是一棵完全二叉樹,因此其任何一非葉節點滿足性質 key i key 2i 1 key i key 2i 2 或者key i key 2i 1 key key 2i 2 即任何一非葉節點的關鍵字不大於或者不小於其左右孩子節點的關鍵...