二分查詢演算法的幾種實現
阿新 • • 發佈:2019-01-02
最簡單的二分
1.迴圈實現
template <typename T> int binary_search(const vector<T> &set, const T &value) { auto low = set.begin(); auto high = set.end(); auto high_dump = high; auto low_dump = low; auto mid = low + ((high - low) >> 1); /*1. mid=(low+high)/2,如果 low 和 high 太大就會產生溢位*/ while ((low <= high) && (mid != high_dump)) /*2. 一定是 <= */ { if (*mid == value) return mid - low_dump; /*3. 一定要+1,-1,不然當 low = high時,就會產生死迴圈*/ if (*mid < value) low = mid + 1; else high = mid - 1; mid = low + ((high - low) >> 1); } return -1; }
2. 遞迴實現
template <typename ForwardIt, class T> bool binary_search(ForwardIt frist, ForwardIt last, const T &value) { if (frist > last) return false; auto mid = frist + ((last - frist) >> 1); if (*mid == value) return true; if (*mid < value) binary_search(mid + 1, last, value); else binary_search(frist, mid - 1, value); }
幾種變式
1.查詢第一個值等於給定值的元素
/* 1.查詢第一個值等於給定值的元素 [1,3,4,5,6,8,8,8,11,18] 找到返回下標,找不到返回 -1 */ template <typename ForwardIt, class T> int binary_search(ForwardIt low, ForwardIt high, const T &value) { auto low_dump = low; auto high_dump = high ; auto mid = low + ((high - low) >> 1); while ((low <= high) && (mid != high_dump)) { if (*mid < value) low = mid + 1; else if (*mid > value) high = mid - 1; else { if ((mid == low_dump) || (*(mid - 1) != value)) return mid - low_dump; else high = mid - 1; /*縮排high的距離*/ } mid = low + ((high - low) >> 1); } return -1; }
2.查詢最後一個值等於給定值的元素
同上
3. 查詢第一個大於等於給定值的元素
/*3.查詢第一個大於等於給定值的元素
[1,3,4,5,6,8,8,8,11,18]
找到返回下標,找不到返回 -1
*/
template <typename ForwardIt, class T>
int binary_search(ForwardIt low, ForwardIt high, const T &value)
{
auto low_dump = low;
auto high_dump = high;
auto mid = low + ((high - low) >> 1);
while ((low <= high) && (mid != high_dump))
{
if (*mid < value)
low = mid + 1;
else if (*mid >= value)
{
if ((mid == low_dump) || (*(mid - 1) < value))
return mid - low_dump;
else
high = mid - 1;
}
mid = low + ((high - low) >> 1);
}
return -1;
}
4. 查詢最後一個小於等於給定值的元素
/*4. 查詢最後一個小於等於給定值的元素
[1,3,4,5,6,8,8,8,11,18]
找到返回下標,找不到返回 -1
*/
template <typename ForwardIt, class T>
int binary_search(ForwardIt low, ForwardIt high, const T &value)
{
auto low_dump = low;
auto high_dump = high;
auto mid = low + ((high - low) >> 1);
while ((low <= high) && (mid != high_dump))
{
if (*mid <= value)
{
if ((mid == high_dump - 1) || (*(mid + 1) > value))
return mid - low_dump;
else
low = mid + 1;
}
else if (*mid > value)
high = mid - 1;
mid = low + ((high - low) >> 1);
}
return -1;
}