The application of binary search algorithm in C + + program example _c language

Source: Internet
Author: User
Tags assert rand

The idea of a binary lookup algorithm is simple, described in programming Zhuji: In an array containing T, the binary lookup solves the problem by the alignment of the range. At the beginning, the range is the entire array. The range is narrowed by comparing the elements in the middle of the range to T and discarding half the range. This process lasts until the T is discovered, or the range that can contain T is empty.
Donald Knuth, in his book sorting and searching, points out that although the first binary lookup algorithm was published as early as 1946, the first binary search algorithm without bugs was published 12 years later. One common bug is the calculation of the subscript for an intermediate value, which, if written (Low+high)/2, may overflow when the low+high is large, resulting in an array access error. The improved method is to write the calculation as follows: low+ ((high-low) >>1). The modified algorithm code is given below:

int binarysearch1 (int a[],int n,int x) 
{ 
 int l,u,m; 
 L=0;u=n; 
 while (L<u) 
 { 
  m=l+ (u-l) >>1); 
  if (X<a[m]) 
   u=m; 
  else if (X==a[m]) return 
   m; 
  else 
   l=m+1; 
 } 
 return-1; 
} 

Note here that the subscript adjustment looks a bit irregular because of the asymmetric range. One is u=m, the other is l=m+1. In fact, very good understanding, the form of adjustment before the interval should be [) form, if the median value is smaller than the lookup value, then the adjustment is the left edge, that is, closed part, so add 1; otherwise, the adjustment is the right edge, is the open part, so do not subtract 1. The form is still [) after adjustment. Of course, it can be written in a symmetrical form. The code is as follows:

int binarysearch1 (int a[],int n,int x) 
{ 
 int l,u,m; 
 l=0;u=n-1; 
 while (L<=u) 
 { 
  m=l+ (u-l) >>1); 
  if (X<a[m]) 
   u=m-1; 
  else if (X==a[m]) return 
   m; 
  else 
   l=m+1; 
 } 
 return-1; 
} 

This also looks more regular, but there is a shortage. If you want to change the program to "pure pointer" form, there will be trouble. The code that modifies the pure pointer is as follows:

int binarysearch2 (int *a,int n,int x) 
{ 
 int *l,*u,*m; 
 l=a;u=a+n-1; 
 while (L<=u) 
 { 
  m=l+ (u-l) >>1); 
  if (x<*m) 
   u=m-1; 
  else if (x==*m) return 
   m-a; 
  else 
   l=m+1; 
 } 
 return-1; 
} 

When n is 0 o'clock, an invalid address is referenced. Asymmetric intervals do not have this problem. The code is as follows:

int binarysearch2 (int *a,int n,int x) 
{ 
 int *l,*u,*m; 
 L=a;u=a+n; 
 while (L<u) 
 { 
  m=l+ (u-l) >>1); 
  if (x<*m) 
   u=m; 
  else if (x==*m) return 
   m-a; 
  else 
   l=m+1; 
 } 
 return-1; 
} 

The binary lookup given above is iterative method implementation, of course, can also be implemented in a recursive way. The code is as follows:

int Binarysearch3 (int a[],int l,int u,int x) 
 
int m=l+ ((u-l) >>1); 
if (l<=u) 
{ 
 if (X<a[m]) return 
  Binarysearch3 (a,l,m-1,x); 
 else if (X==a[m]) return 
  m; 
 else return 
  Binarysearch3 (a,m+1,u,x); 
} 
return-1; 


These binary algorithms, if the array elements are duplicated, return an element of the repeating element. If you want to return the location where the lookup element first appears, you need to modify the code. A solution is given below:

int binarysearch4 (int a[],int n,int x) 
{ 
 int l,u,m; 
 int flag=-1; 
 L=0;u=n; 
 while (L<u) 
 { 
  m=l+ (u-l) >>1); 
  if (X<a[m]) 
   u=m; 
  else if (X==a[m]) 
   flag=u=m; 
  else 
   l=m+1; 
 } 
 return flag; 
} 

The following is the solution in programming Zhuji:

int binarysearch4 (int a[],int n,int x) 
{ 
 int l,u,m; 
 L=-1;u=n; 
 while (L+1<u) 
 { 
  m=l+ (u-l) >>1); 
  if (a[m]<x) 
   l=m; 
  else 
   u=m; 
 } 
 Return (u>=n| | a[u]!=x)? -1:u; 


At the end of the code discussion for the binary algorithm, the following is a discussion of the test questions for the program. "Beauty of Code" has a chapter devoted to the test of the binary search algorithm, very beautiful. Here, a few test cases are given. For Binarysearch1. The test procedure is as follows:

#include <iostream> #include <cassert> #include <algorithm> #include <ctime> using namespace 
 
Std 
int calmid (int l,int u) {return l+ ((u-l) >>1);} 
 
int binarysearch1 (int a[],int n,int x); 
 #define BS1 BINARYSEARCH1 int main () {long start,end; 
 
 Start=clock (); 
 int a[9]={-2147483648,-13,-10,-5,-3,0,1,400,2147483647}; 
 The Test assert (Calmid (0,1) ==0) of the value subscript calculation; 
 ASSERT (Calmid (0,2) ==1); 
 ASSERT (Calmid (1000000,2000000) ==1500000); 
 ASSERT (Calmid (2147483646,2147483647) ==2147483646); 
 
 ASSERT (Calmid (2147483645,2147483647) ==2147483646); 
 Smoke Test assert (BS1 (a,9,0) ==5); 
 ASSERT (BS1 (a,9,1) ==6); 
 
 ASSERT (BS1 (a,9,2) ==-1);       Boundary Test assert (BS1 (a,0,1) ==-1);  0 element assert (BS1 (a,1,-2147483648) ==0);  1 elements succeeded assert (BS1 (a,1,-2147483647) ==-1);  1 element Failure assert (BS1 (a,9,-2147483648) ==0);       First element assert (BS1 (a,9,-3) ==4);  Intermediate element assert (BS1 (a,9,2147483647) ==8); 
 End element//Automated test int b[10000]; 
 int i,j; for (i=0;i<10000;i++) {b[i]=i*10; 
   for (j=0;j<=i;j++) {assert (BS1 (b,i+1,j*10) ==j); 
  ASSERT (BS1 (b,i+1,j*10-5) ==-1); 
 }///Automated testing introduces random number Srand (time (0)); 
  for (i=0;i<10000;i++) {B[i]=rand ()%1000000; 
  Sort (&b[0],&b[i]); 
   for (j=0;j<=i;j++) {int X=rand (); 
   int K=BS1 (B,I+1,X); 
  if (K!=-1) assert (B[K]==X); 
 } end=clock (); 
 cout<< (End-start)/1000.0<< ' s ' <<endl; 
return 0; 
 }

Notice that the elements of the array have positive, negative, 0, maximum, and minimum values. Often forget negative tests, introducing both maximum and minimum values, mainly for boundary testing.
First, the calculation of the median subscript is tested. In addition a small function was written, which was tested separately. Given that the memory may not fit such a large array, it is only a mock test, and there is no real request for such a large space, but for the median subscript the test is sufficient.
Second, smoke tests. That is to do some of the most basic tests. Boundary tests are performed after the test passes.
Third, the boundary test. Here are three types, one for the number of array elements, 0, 1 respectively. The second is for the element position, respectively, is the first element, the middle element, the end element. Three is for the element value, has the maximum value, the minimum value, 0 and so on test.
Four, automated testing. This automatically generates an array of tests, and then a successful lookup test for each element.
The other is automated testing, except that the elements of an array are random values.
Five, performance test. The relevant code is not listed here. When all the above tests pass, you can modify the lookup algorithm to add the code for the performance test. In fact, you can simply add a comparison counter. The return value is changed from the original lookup result to the counter value of the comparison. The code is simpler and is not listed.

Note: Two-point search for a bug that is easy to ignore
for the binary search algorithm, I believe we will certainly not unfamiliar. The algorithm finds the specified element from a sorted array and returns 1 if the index of the element is returned in the array. The solution is given below.

A is a sorted array, n is the size of the arrays, x is the specified element 
int binarysearch (int a[], int n, int x) 
{int left 
 = 0, right = n-1, middle = 0;
   
    int tmp = 0; 
 While [left <= right] 
 { 
   middle = (left + right)/2; 
   TMP = A[middle]; 
   if (x < tmp) right = middle-1; 
   else if (x > tmp) left = middle + 1; 
   else return middle; 
 } 
 return-1; 
} 

   

At first glance there is no error, but unfortunately, there is a bug in the program. When the array is large, (left+right) may be negative, the array subscript overflows, and the program crashes.
Solution: Change middle= (Left+right)/2 to middle=left+ (Right-left)/2. The use of subtraction instead of addition, thereby eliminating the overflow.
Reference from the beauty of code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.