Wonder233的學習部落格
阿新 • • 發佈:2019-01-09
折半查詢(二分查詢)
概念
每次取中間記錄查詢的方法。
前提
線性表中的記錄必須是關鍵碼有序(通常從小到大有序),線性表必須採用順序儲存。
基本思想
在有序表中,取中間記錄作為比較物件:
- 若給定值與中間記錄的關鍵字相等,則查詢成功;
- 若給定值小於中間記錄的關鍵字,則在中間記錄的左半區繼續查詢;
- 若給定值大於中間記錄的關鍵字,則在中間記錄的右半區繼續查詢。
不斷重複上述過程,直到查詢成功,或所有查詢區域無記錄,查詢失敗為止。
演算法實現
function Binary_Search(a,key){
var low,high,mid;
low = 0 ; /* 定義最低下標為記錄首 */
high = a.length-1; /* 定義最高下標為記錄尾 */
while (low <= high) {
mid = parseInt((low + high) / 2); /* 折半 */
if (key < a[mid]) { /* 若查詢值比中值小 */
high = mid - 1; /* 最高下表調整到中間下標小一位 */
}else if(key >a[mid]){ /* 若查詢值比中值大 */
low = mid + 1; /* 最低下表調整到中間下標大一位 */
}else{
return mid; /* 若相等則說明 mid 即為查詢到的位置 */
}
}
return a.length; /* 返回原陣列長度則說明查詢失敗 */
}
時間複雜度分析
折半演算法的時間複雜度為
對於需要頻繁執行插入或刪除操作的資料集來說,維護有序的排序會帶來不小的工作量,因此不建議使用折半演算法。
插值查詢
基本思想
折半查詢最關鍵的一段程式碼就是求中間值:
也就是
考慮將這個
假設
但如果用新方法:
插值查詢是根據要查詢的關鍵字 key 與查詢表中最大最小記錄的關鍵字比較後的查詢方法,其核心就在於插值的計算公式:
key−a[low]a[high]−a[low]
演算法實現
/* 插值查詢 */
function Interpolation_search(a,key){
var low,high,mid;
low = 0; /* 定義最低下標為記錄首 */
high = a.length-1; /* 定義最高下標為記錄尾 */
while (low <= high) {
mid = parseInt(low + (key -a[low]) / (a[high]-a[low])*(high-low)); /* 插值 */
if (key < a[mid]) { /* 若查詢值比中值小 */
high = mid - 1; /* 最高下表調整到中間下標小一位 */
}else if(key >a[mid]){ /* 若查詢值比中值大 */
low = mid + 1; /* 最低下表調整到中間下標大一位 */
}else{
return mid; /* 若相等則說明 mid 即為查詢到的位置 */
}
}
return a.length; /* 返回原陣列長度則說明查詢失敗 */
}
時間複雜度分析
也是