##二分查找法 
- 二分查找法又称折半查找,它是一种效率较高的查找方法。 
- 二分查找要求:线性表是有序表,即表中的结点按关键字有序,并且要用向量作为表的存储结构。我们设有序表是[递增]有序的。 
 
##二分查找的基本思想 
在一个已经排序好的序列(递增序列)R[low,---,mid,---,high]当中,查找我们想要查找的元素x。从表的中间取出元素mid与我们要查找的元素x进行比较,如果x > mid,则x 在mid和high区间。小于mid则在low和mid之间。然后在新的区间重新取mid继续查找,直到取出的mid == x或者范围内全部查询完毕。 
 
##伪代码 
```` 
low = 0, high = n - 1; 
while (low < high) 
        mid = (low + high) / 2; 
        case: 
                R[mid] < x: low = mid + 1; 
                R[mid] = x: p = mid; break; 
                R[mid] > x: high = mid - 1; 
return -1; 
```` 
##第一个程序 
 
```` 
int binarysearch (int array[], int n, int target) { 
        int low, high, mid; 
        low = 0, high = n - 1; 
        while (low <= high) { 
                mid = (low + high) / 2; 
                if (array[mid] < target) { 
                        low = mid + 1; 
                } else if (array[mid] > target) { 
                        high = mid - 1; 
                } else { 
                        return mid; 
                } 
        } 
        return -1; // the array does not contain the target. 
} 
```` 
 
##第二个程序(递归) 
```` 
int binarysearch (int array[], int low, int high, int target) { 
        if (low > high) return -1; 
        int mid = (low + high) / 2; 
        if (array[mid] > target)  
                return binarysearch (array, low, mid - 1; target); 
        if (array[mid] < target) 
                return binarysearch (array, mid + 1; high, target); 
        //if (array[mid] == target) 
                return mid; 
} 
```` 
##使用二分查找法寻找边界值 
之前是在数组中找到一个数要与目标值相等,如果不存在则返回 -1。我们也可以用二分法寻找边界值。也就是找到有序数组中“刚好大于”或“刚好小于”目标数的那个数。  
###使用二分法查找上届 
```` 
int array[] = {2, 3, 5, 7, 11, 13, 17}; 
int target = 7; 
 
//find the first element, whose value is larger than target, in a sorted array 
int BSearchUpperBound (int array[], int low, int high, int target) { 
        // Array is empty or target is larger than any every element in array 
        if (low > high || target >= array[high]) return -1; 
         
        int mid = (low + high) / 2; 
        while (high > low) { 
                if (array[mid] > target) 
                        high = mid; 
                /* 与精确查找不同,精确查找存在大于,小于,和等于。而界限查找只存在 大于和不大于。如果找到的数大于当前的目标数,它就有可能是我们找的数,所以要保留这个索引,因此此处没有 -1 */ 
                else 
                        low = mid + 1; 
                /* 这里是不大于目标数,所以要 +1 */ 
                         
                mid = (low + high) / 2; 
        } 
        return mid; 
} 
```` 
###使用二分法查找下届 
```` 
//Find the last element, whose value is less than target, in a sorted array 
int BSearchLowerBound (int array[], int low, int high, int target) { 
        //Array is empty or target is less than any every element in array 
        if (low > high || target <= array[low]) return -1; 
         
        int mid = (low + high) / 2; 
        while (low < high) { 
                if (array[mid] < target) 
                        low = mid; 
                else 
                        high = mid - 1; 
                         
                mid = (low + high) / 2; 
        } 
         
        return mid; 
} 
```` 
 
##使用二分法查找区域 
之前的查找都是基于数组中的元素各不相同。假如存在重复的数据,而数组依然有序,那么我们可以使用二分法查找判别目标数是否存在。不过,返回的index就只能是随机的重复数据中的某一个。所以我们会希望知道有多少个目标数存在,或者说我们希望得到该数据在数组的区域。结合前面的界限查找,我们只要找到目标数严格的上届和下届,那么界限之间的数据(不包括界限)就是我们数据区域。 
 
```` 
// return type: pair <int, int> 
// the first value indicate the begining of range 
// the second value indicate the end of range 
// If target is not find, (-1, -1)will be returned 
 
pair <int, int> SearchRange (int A[], int n, int target) { 
        pair <int, int>  r(-1, -1); 
        if (n <= 0) return r; 
         
        int lower = BSearchLowerBound (A, 0, n - 1, target); 
        lower = lower + 1; //move to next element 
         
        if (A[lower] == target) 
                r.first = lower; 
        else //target is not in the array 
                return r; 
                 
        int upper = BSearchUpperBound (A, 0, n - 1, target); 
        upper = upper < 0 ? (n - 1) : (upper - 1); move to previous element 
        /* 这个地方我不太懂可能有错误 */ 
         
        //since in previous search we had check whether the target is 
        //in the array or not, we do not need to check it here again 
        r.second = upper; 
         
        return r; 
} 
```` 
 
##参考 
[二分法的实现与汇总](http://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html) |