資料結構基礎 尋找 之 二分尋找,資料結構二分
【演算法思想】
二分尋找又稱折半尋找,對排好序的數組,每次取這個數和數組中間的數進行比較,複雜度是O(logn)
如:設數組為a[n],尋找的數x,
如果x==a[n/2],則返回n/2;
如果x < a[n/2],則在a[0]到a[n/2-1]中進行尋找;
如果x > a[n/2],則在a[n/2+1]到a[n-1]中進行尋找;
優點是比較次數少,尋找速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。
條件:尋找的數組必須要為有序數組。
【遞迴方法源碼】
/* arrat:數組 , low:上界; high:下界; target:尋找的資料; 返回target所在數組的下標 */ int binarySearch(int array[], int low, int high, int target) { int middle = (low + high)/2; if(low > high) { return -1; } if(target == array[middle]) { return middle; } if(target < array[middle]) { return binarySearch(array, low, middle-1, target); } if(target > array[middle]) { return binarySearch(array, middle+1, high, target); } }
【非遞迴方法源碼】
/* arrat:數組 , n:數組的大小; target:尋找的資料; 返回target所在數組的下標 */ int binarySearch2(int array[], int n, int target) { int low = 0, high = n, middle = 0; while(low < high) { middle = (low + high)/2; if(target == array[middle]) { return middle; } else if(target < array[middle]) { high = middle; } else if(target > array[middle]) { low = middle + 1; } } return -1; }
遞迴與非遞迴方法,應該注意到,遞迴方式high是上界,也就是array的lenth()-1,變換 mid 的時候有增1和減1操作;
非遞迴的方法是size()是上界,也就是array的lenth(),變換 mid 的時候有增1操作而沒有減1操作;
這 2 點一定要引起重視!!!
【STL方法實現二分尋找】
STL中關於二分尋找的函數主要有三個,分別是lower_bound/upper_bound/
binary_search。這三個函數都運用於有序區間,當然這也是二分尋找思想運用的前提,下面逐一對這三個函數進行剖析。
這三個函數都包含在演算法庫中,因此首先應該包含標頭檔,如下所示:
#include <algorithm>using namespace std;
lower_bound演算法返回一個非遞減序列[first, last)中的第一個大於等於val的位置。
upper_bound演算法返回一個非遞減序列[first, last)中的第一個大於val的位置。
ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp);ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp);
STL源碼實現
Template <class ForwardIterator, class T> bool binary_search(ForwardIterator first, ForwardIterator last, const T& value) { ForwardIterator i = lower_bound(first, last, value); //這裡的實現就是調用的lower_bound ,並且如果元素不存在那麼lower_bound指向的元素一定是 operator 為ture的地方。 return i != last && !(value < *i);// 返回是否尋找到,而不是元素索引}
參考詳址:
http://blog.csdn.net/luoweifu/article/details/16656737
http://blog.csdn.net/u012878643/article/details/46723609
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。