參考文章:二
分查詢,你真的掌握了嗎?
目標:在乙個有序的陣列中,找出指定資料所處的位置。
時間複雜度就是重複次數的同一量級(order),通俗講就是迴圈次數的同一量級啦。這樣看,
初始時,查詢範圍大小為n(陣列的長度)
第一次迴圈後,查詢範圍大小為n/2
第二次迴圈後,查詢範圍大小為n/4
第三次迴圈後,查詢範圍大小為n/8
......
第k次迴圈後,查詢範圍大小為n/(2^k)
迴圈停止的的條件就是n/(2^k)<=2,則2^k=n/2,k=log2 n/2=o(logn)
#include#includeusing namespace std;
void main(void)
; int target = 25;
int minn, midn,maxn;
minn = 0;
maxn = 9;
while (minn <= maxn)
else if (teststr[midn] > target)
else
}cout << "not found" << endl;
}
執行結果↓
q1:為什麼要midn = minn + (maxn - minn) / 2?
a1:其實就是想表達midn=(minn+maxn)/2,
但是,
//使用(low+high)/2會有整數溢位的問題
//(問題會出現在當low+high的結果大於表示式結果型別所能表示的最大值時,
//這樣,產生溢位後再/2是不會產生正確結果的,而low+((high-low)/2)不存在這個問題
測試一下,int在vs2013是32位的,最大4294967295≈4*10^9;看下面**
#include#includeusing namespace std;
void main(void)
執行結果↓
看見木有?midn = (minn + maxn) / 2中,由於
minn + maxn=6*10^9
=(33位二進位制)1 0110 0101 1010 0000 1011 1100 0000 0000
最高位溢位,就等於
(32位二進位制)
0110 0101 1010 0000 1011 1100 0000 0000
=1705032704
最後1705032704/2=852516352,便是得到的結果。
而midn = minn + (maxn - minn) / 2中,只要maxn和minn不溢位,整個式子就不會溢位。
q2:為什麼要maxn = midn-1和minn = midn+1?
a2:同樣,按照原始思想,其實就是想表達maxn=midn以及minn=midn。為什麼要這樣呢?
舉個栗子,中,查詢25,如果**是↓
#include#includeusing namespace std;
void main(void)
; int target = 25;
int minn, midn, maxn;
minn = 0;
maxn = 9;
while (minn <= maxn)
else if (teststr[midn] > target)
else
}cout << "not found" << endl;
}
你會發現陷入死迴圈了。分析一下
進迴圈之前:1,5,8,9,12,15,18,19,24,25
第一次迴圈後:
1,5,8,9,12,15,18,19,24,
25
第二次迴圈後:
1,5,8,9,12,15,18,19,24,
25
第三次迴圈後:
1,5,8,9,12,15,18,19,24,25
第四次迴圈後:
1,5,8,9,12,15,18,19,24,
25
第五次迴圈後:
1,5,8,9,12,15,18,19,24,
25
第六次迴圈後:
1,5,8,9,12,15,18,19,24,25
......
so as you see...
還有另外一點原因呢,就是優化啦,比如第一次迴圈後:
1,5,8,9,12,15,18,19,24,
25,已知了12不是target了,就往前再進乙個,更加縮短了範圍。
二分查詢演算法解析(java版)
1 確定該區間的中點位置 mid low high 2 min代表區間中間的結點的位置,low代表區間最左結點位置,high 代表區間最右結點位置 2 將待查 a值與結點 mid的關鍵字 下面用 r mid key 比較,若相等,則查詢成功,否則確定新的查詢區間 如果 r mid key a 則由表...
查詢演算法 二分查詢
利用二分查詢演算法查詢某乙個元素,前提條件是該被查詢的元素是乙個已經有序的陣列。二分查詢的思想是將陣列元素的最高位 high 和最低位 low 進行標記,取陣列元素的中間 mid 和和要查詢的值 key 進行比較,如果目標值比中間值要大,則將最低位設定為mid 1,繼續進行查詢。如果目標值小於中間值...
查詢演算法 二分查詢
二分查詢的思路是很簡單的,前提是這組資料是有順序的。思路是從中間找乙個數,判斷大小,如果數比中間數大,說明在中間數到結尾的數中,如果小於,則說明在開始和中間數之間,經過多次相同操作,就可以得到我們想查詢的數時間複雜度就是 o logn 非遞迴的實現 const testarr let i 0whil...