1. Problem Introduction
Recently ran the Academy online course data structure (Fall 2015). The course was presented by Deng Junhui, a teacher at Tsinghua University, who had encountered such a range of topics after completing the homework. In this topic, I need to solve a sub-problem: Given a set of ordered integers set A[0...N] and a set of closed intervals [l,r], the number of points in this set of integers that fall within this interval.
To solve this problem, it is easy to think of finding a very efficient binary search, but this is not the general question of whether a key is a binary search in an array. For the interval left endpoint L, find the subscript Indexl of the array that is greater than or equal to its smallest element. For the interval right endpoint R, find the subscript indexr in the array that is less than or equal to its largest element.
2. Realize the realization of 2.1 lower bound in detail 1. First consider the interval left endpoint L, we want to find the smallest value in the array that is greater than or equal to L.
We can write pseudo-code about the conditional Judgment part:
If A[mid] >= key//so the array a[begin,mid] There must be elements we require
end = Mid;
Else//a[mid] < Key, the element we are asking for must be in the array a[mid+1,end]
Begin = mid + 1;
2. Secondly, according to the judging conditions, we can write the formula of middle value mid, where the main problem is to take the upper bound or the lower bound.
Consider the case where there are only two elements left A[i,i+1].
If the upper bound is: Mid = (begin+end+1)/2 = (i+i+1+1)/2 = i+1, then if the condition A[mid]=a[i+1]>=key is met, continue with the left branch interval A[begin,mid] of the iteration, is still equivalent to the last interval a[begin,end], because the interval size does not shrink, so that the left branch into a dead loop. If the conditional A[mid]=a[i+1]<key is met, the right branch interval a[mid+1,end], equivalent to the interval a[end+1,end] exits directly because the loop condition is not met. In short, we can not draw the correct judgment result.
If the boundary is removed, i.e.: Mid = (begin+end)/2 = (i+i+1)/2 = i, then if the condition A[mid]=a[i]>=key is met, the left branch interval A[begin,mid] to continue the iteration is equivalent to the interval a[begin,begin ], the interval size is reduced to one, there will be no scale remains unchanged and the phenomenon of a dead cycle. If the condition A[mid]=a[i]<key, the right branch interval a[mid+1,end], equivalent to the interval a[end,end], the interval size is reduced to one, there will be no dead loop phenomenon, can continue to process downward.
Therefore, mid should be calculated as the lower bound, i.e. mid = (begin+end)/2.
3. Consider the end condition of the entire cycle.
We can proceed with the analysis of the second step. For example, there are only two elements left a[i]=3,a[i+1]=7, and key=5. Mid= (i+i+1)/2=i, A[mid]=a[i]=3<7, and then in the interval a[i+1,i+1] further judgment. If you do not exit the loop, that is, the maintenance condition of the loop is begin<=end, but further processing. Mid= (i+1+i+1)/2=i+1, a[mid]=a[i+1]=7>=5, and then further processing in the zone a[i+1,i+1]. Due to the next begin=i+1, end=i+1, according to the previous cycle to maintain the conditions begin<=end, can not exit the loop, so you will fall into a dead loop. The subscript for the smallest element that is greater than or equal to the key value should be i+1. So our cyclic maintenance conditions should be changed to: Begin < End. In this way when processing interval a[i+1,i+1], due to begin=i+1, end=i+1, does not satisfy the cyclic maintenance condition begin<end, exits the loop. But we cannot directly return to the subscript of begin at this time as a result, as there may be errors. We have to judge if the element corresponding to the begin is indeed greater than or equal to key, then begin is the corresponding subscript, otherwise, the element we are looking for does not exist, and we can return-1, indicating that it was not found. The corresponding case is not found in the array a[begin,end] all elements are less than key.
In the end, the condition of our cyclic maintenance is: Begin<end.
4. Lower bound Implementation code
1 //Binary finds the subscript of the smallest element greater than or equal to the key value2 intBinsearchlowerbound (intArray[],intNintkey) {3 intBegin =0;4 intEnd = N-1;5 //to ensure that there is a correct result, the termination condition of the loop must be: begin = = End6 while(Begin <end) {7 //due to the following judging conditions two branches were produced: 1. [Begin, Mid] 2. [Mid+1, end]8 //mid must be calculated using: Mid = (begin+end)/2, which is the method of rounding down9 //to ensure that all two branches can exit the loop normally .Ten intMID = begin + (End-begin)/2; One if(Array[mid] < key)//if it is less than the key value, the element you are looking for must be in the interval [mid+1, end] ABegin = Mid +1; - Else //if it is greater than or equal to the key value, the element you are looking for must be in the interval [begin, Mid] -End =mid; the } - //There are two scenarios after exiting the loop: 1. The element being searched for exists 2. The element being found does not exist, at which point all elements are less than key - //It is therefore to be judged, if present, to return the subscript. If not present, returns-1, indicating no - if(Array[begin] >=key) + returnbegin; - Else + return-1; A}
Realization of 2.2 upper bound
The analysis process is the same as 2.1 lower bound, the following is only the specific implementation code
1 //binary finds the subscript that is less than or equal to the maximum value of the key value2 intBinsearchupperbound (intArray[],intNintkey) {3 intBegin =0;4 intEnd = N-1;5 //to ensure that there is a correct result, the termination condition of the loop must be: begin = = End6 while(Begin <end) {7 //due to the following judging conditions two branches were produced: 1. [Begin, Mid-1] 2. [Mid, end]8 //mid must be calculated using: Mid = (begin+mid+1)/2, which is the method of rounding up9 //to ensure that all two branches can exit the loop normally .Ten intMID = begin + (end-begin+1)/2; One if(Array[mid] > key)//if it is greater than the key value, the element being searched must be in the interval [begin, Mid-1] AEnd = Mid-1; - Else -begin = Mid;//If the value is less than or equal to the key, the element you are looking for must be in the interval [Mid, end] the } - //There are two cases after exiting the loop: 1. The element being searched for exists 2. The element being searched for does not exist, at which point all elements are greater than the key value - //It is therefore to be judged, if present, to return the subscript. If not present, returns-1, indicating no - if(Array[begin] <=key) + returnbegin; - Else + return-1; A}
3. Main program for testing
The specific code is:
1#include <iostream>2 3 using namespacestd;4 5 Const intLEN =4;6 7 intMainintargcConst Char*argv[]) {8 intA[len];9printf"Please enter%d numbers that are already sorted: \ n", LEN);Ten for(inti =0; i < LEN; i++) OneCIN >>A[i]; Acout <<"Please enter the left interval endpoint value to find:"<<Endl; - intL; -CIN >>L; the intINDEXL =Binsearchlowerbound (A, LEN, L); -printf"The subscript for the minimum value greater than or equal to%d is%d\n", L, INDEXL); -cout <<"Please enter the right interval endpoint value to find:"<<Endl; - intR; +CIN >>R; - intINDEXR =Binsearchupperbound (A, LEN, R); +printf"The subscript for the maximum value less than or equal to%d is%d\n", R, INDEXR); A return 0; at}
Realization and analysis of upper bound and lower bound in binary search