Description
Author: So Who
Blog:http://www.cppblog.com/converse
Reprint please indicate the source.
The basic idea of binary search algorithm
The precondition of the binary lookup algorithm is an already ordered sequence (in this article to illustrate the convenience of the problem, assuming that the sequence is in ascending order), so that when looking for the element to find, first and the sequence of elements in the middle of the comparison, if greater than this element, in the second half of the current sequence to continue to find, If it is less than this element, the first half of the current sequence continues to be searched until the same element is found, or the range of the searched sequence is empty.
Using pseudo-code, the binary lookup algorithm is roughly what it looks like:
0, right = N-1 while (left <= right ) 2case < t: 1; = t: Break ; > t: Right = mid-1; return -1;
The first correct program
Based on the algorithm thought and pseudo-code given above, we give the first correct program, but it also has some small problems, which will be discussed later
intSearchintArray[],intNintv) { intLeft , right, middle; Left=0, right = N-1; while(Left <=Right ) {Middle= (left + right)/2; if(Array[middle] >v) { Right=Middle; } Else if(Array[middle] <v) { left=Middle; } Else { returnMiddle; } } return-1;}
The following is a discussion of some of the problems that may occur when you write a binary lookup algorithm.
Problems caused by boundary errors
Binary search algorithm boundary, generally divided into two cases, one is left closed to open the interval, similar to [left, right), one is closed to the closing of the closed interval, similar to [leave, OK]. It is important to note that the initialization conditions outside the loop, and the iterative steps in the loop body, Must abide by a consistent interval rule, that is, if the loop body is initialized with the left closed right opening interval as the boundary, so should the iteration inside the loop body. If the two are inconsistent, it can cause a program error. For example, the following is the error binary lookup algorithm:
intSearch_bad (intArray[],intNintv) { intLeft , right, middle; Left=0, right =N; while(Left <Right ) {Middle= (left + right)/2; if(Array[middle] >v) { Right= Middle-1; } Else if(Array[middle] <v) { left= Middle +1; } Else { returnMiddle; } } return-1;}
The error of this algorithm is that when the loop is initialized, the right=n is initialized, that is, the left-closing right-open interval is used, and the condition of satisfying array[middle] > v is that v if present should be in the [left, middle) interval, But here the right is assigned to middle-1, so that if it happens that middle-1 is the element of the lookup, then this element will not be found.
The following gives two algorithms, namely the correct left closed right and left closed right open interval algorithm, can be compared with the above:
intSEARCH2 (intArray[],intNintv) { intLeft , right, middle; Left=0, right = N-1; while(Left <=Right ) {Middle= (left + right)/2; if(Array[middle] >v) { Right= Middle-1; } Else if(Array[middle] <v) { left= Middle +1; } Else { returnMiddle; } } return-1;}intSEARCH3 (intArray[],intNintv) { intLeft , right, middle; Left=0, right =N; while(Left <Right ) {Middle= (left + right)/2; if(Array[middle] >v) { Right=Middle; } Else if(Array[middle] <v) { left= Middle +1; } Else { returnMiddle; } } return-1;}
Dead loop
The above situation is only one of the boundaries of the wrong write, that is, the right side of the boundary value is wrong, if both are written incorrectly, may cause a dead loop, such as the following program:
intSearch_bad2 (intArray[],intNintv) { intLeft , right, middle; Left=0, right = N-1; while(Left <=Right ) {Middle= (left + right)/2; if(Array[middle] >v) { Right=Middle; } Else if(Array[middle] <v) { left=Middle; } Else { returnMiddle; } } return-1;}
This program uses a left-closed right-hand interval. However, when Array[middle] > V, then the next time to find the interval should be [middle + 1 right], and here it becomes [middle, OK]; when Array[middle] < V, then the next search interval should be [left, middle-1], and here it will be. There is a problem with the selection of two boundaries, so it is possible that a search is always rotated between the two ranges, resulting in a dead loop of the program.
Overflow
Before resolving the boundary selection problems may occur, the following to solve another problem, in fact, this problem is strictly not an algorithmic problem, but I notice that many places are not mentioned, I think it is better to mention.
In the body of the loop, the expression is used when calculating the intermediate position:
2;
If the sum of left and right exceeds the representation range of the type, then middle will not get the correct value.
So, the more prudent approach should be this:
2;
More sophisticated algorithms
As we said earlier, the first algorithm given is a "correct" program, but there are some small problems.
First, if there are multiple identical elements in the sequence, it is not always possible to find the position of the first element each time, for example, consider an extreme case where there is only one element in the sequence, and when looking for this element, it is clear that the position of the intermediate element is returned.
Secondly, in the previous algorithm, there are three times in each loop body, two comparisons, there is no way to reduce the number of comparisons further optimization procedures?
<< programming Zhu Ji Nanxiong >> gives the algorithm to solve these two problems, combined with the above-mentioned overflow problem, I have also modified the calculation of middle:
intSEARCH4 (intArray[],intNintv) { intLeft , right, middle; Left= -1, right =N; while(Left +1!=Right ) {Middle= left + (right-left)/2; if(Array[middle] <v) { left=Middle; } Else{ Right=Middle; } } if(Right >= n | | array[right]! =v) { Right= -1; } returnRight ;}
This algorithm is the most perfect one of all the algorithms given here, correct, accurate and high efficiency.
Resources
1.<< programming Zhu Ji Nanxiong >>
Description of the binary lookup on 2.wiki: Http://en.wikipedia.org/wiki/Binary_search
"Turn" two-point search algorithm study notes