首先說下普通二分查詢的思路
普通二分查詢是在乙個沒有重複的排序陣列中,找到目標值
思路就是先從中間找,如果中間值大於目標值,說明目標值在左半區
如果中間值小於目標值,說明目標值在右邊,
當中間值等於目標值,返回他的下標,
// 這裡的陣列預設都不為空
// 給定乙個有序陣列和乙個關鍵字,找到該值在陣列中的下標,否則返回-1一般人可能直接這樣寫:int mid = (left + right) / 2,不能說錯誤,但存在問題:如果 left 和 right 比較大的話,兩者之和就有可能會溢位。int binary_search(vectorvec, int
target)
return -1; //
不存在}
改進的方法是將 mid 的計算方式寫成left + (right-left)/2。
更進一步,如果要將效能優化到極致的話,我們可以將這裡的除以 2 操作轉化成位運算left + (right-left)>>1。
因為相比除法運算來說,計算機處理位運算要快得多。
當出現的目標值有重複的怎麼找
變種一:查詢第一次出現的目標值
我們對陣列data進行二分,如果陣列中間的數字小於k,說明k應該出現在中間位置的右邊;
如果陣列中間的數字大於k,說明k應該出現在中間位置的左邊;
如果陣列中間的數字等於k,並且中間位置的前乙個數字不等於k,
說明這個中間數字就是數字k出現的第乙個位置。否則在左邊找
int binary_search(vectorvec, int找出最後乙個出現的目標數,思路和一類似target)
}return -1
;}
//找最後乙個出現的,同上面類似,只要修改相等的
int binary_search(vectorvec, int
target)
}return -1
;}
#include #include完整**using
namespace
std;
int binary_search1(vectorvec, int
target)
return -1; //
不存在}
//查詢重複陣列中第乙個出現給定值
/*思路, 和普通的二分改變的是當等於給定值需要修改
我們對陣列data進行二分,如果陣列中間的數字小於k,說明k應該出現在中間位置的右邊;
如果陣列中間的數字大於k,說明k應該出現在中間位置的左邊;
如果陣列中間的數字等於k,並且中間位置的前乙個數字不等於k,
說明這個中間數字就是數字k出現的第乙個位置。
*/int binary_search2(vectorvec, int
target)
}return -1;}
//找最後乙個出現的,同上面類似,只要修改相等的
int binary_search3(vectorvec, int
target)
}return -1;}
intmain()
; cout
<< binary_search1(vec1, 4) <
//含有重複的,找出第乙個等於給定值的下標
vector vec2 = ;
cout
<
第一次出現2的下標
"<2) <
//含有重複的,找出最後乙個等於給定值的下標
cout <
最後一次出現2的下標
"<2) <
return0;
}
普通二分也可以遞迴實現
//二分查詢的遞迴實現
int bsearch1(vectora, int n, int
value)
int bsearchinternally(vectora, int low, int high, int
value)
else
if (a[mid]
else
}
二分查詢及其變種
返回帶查詢元素key的下標。若沒有key元素,則返回 1。注意 1 while迴圈的條件是low high 2 每次迭代hi mid 1 或lo mid 1 二分查詢,找到該值在陣列中的下標,否則為 1 static int binaryserach int array,int key else i...
二分查詢及其變種
3 二分查詢變種總結 時間複雜度概念還不清楚的可以先看 這個文章 由於二分查詢每次查詢都是從陣列中間切開查詢,所以每次查詢,剩餘的查詢數為上一次的一半,從下表可以清晰的看出查詢次數與剩餘元素數量對應關係 肯定是大於等於1,也就是n 2 k frac 2k n 1,我們計算時間複雜度是按照最壞的情況進...
二分查詢演算法及其變種
前言 二分查詢演算法也稱為折半查詢演算法,是一種在查詢演算法中普遍使用的演算法。其演算法的基本思想是 在有序表中,取中間的記錄作為比較關鍵字,若給定值與中間記錄的關鍵字相等,則查詢成功 若給定的值小於中間記錄的關鍵字,則在中間記錄的左半區間繼續查詢 若給定值大於中間記錄的關鍵字,則在中間記錄的右半區...