C++二分查找别写错了!

  在C++中,二分查找是一个很好用的玩意,主打一个快(平均时间复杂度log n),前提是序列要有序。But,我估计很多人都写错过,或者正在写错的路上(像我)……

    多的不说,直接上错误案例:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 5     int l = 1,r = 20;
 6     int target,mid;target = 6; //目标值为6 
 7     while(l <= r){
 8         mid = (l+r)/2;
 9         if(a[mid] < target)l = mid+1;
10         else if(a[mid] > target)r = mid-1;
11     }
12     cout << mid << " " << a[mid];
13     return 0;
14 }

第二个:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 5     int l = 1,r = 20;
 6     int target,mid;target = 6; //目标值为6 
 7     while(l < r){ //改了这 
 8         mid = (l+r)/2;
 9         if(a[mid] < target)l = mid+1;
10         else if(a[mid] > target)r = mid-1;
11     }
12     cout << mid << " " << a[mid];
13     return 0;
14 }

 

 第三个:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 5     int l = 1,r = 20;
 6     int target,mid;target = 6; //目标值为6 
 7     while(l < r){ 
 8         mid = (l+r)/2;
 9         if(a[mid] < target)l = mid;//改了这 
10         else if(a[mid] > target)r = mid;//改了这 
11     }
12     cout << mid << " " << a[mid];
13     return 0;
14 }

卡死循环了

 
第四个:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 5     int l = 1,r = 20;
 6     int target,mid;target = 6; //目标值为6 
 7     while(l <= r){ //改了这 
 8         mid = (l+r)/2;
 9         if(a[mid] < target)l = mid;//改了这 
10         else if(a[mid] > target)r = mid;//改了这 
11     }
12     cout << mid << " " << a[mid];
13     return 0;
14 }

卡死循环了

第五个:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    int l = 1,r = 20;
    int target,mid;target = 6; //目标值为6 
    while(l <= r){
        mid = (l+r+1)/2;//改了这 
        if(a[mid] < target)l = mid;//改了这 
        else if(a[mid] > target)r = mid;//改了这 
    }
    cout << mid << " " << a[mid];
    return 0;
}

卡死循环了

第六个:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 5     int l = 1,r = 20;
 6     int target,mid;target = 6; //目标值为6 
 7     while(l < r){//改了这 
 8         mid = (l+r+1)/2;//改了这 
 9         if(a[mid] < target)l = mid;//改了这 
10         else if(a[mid] > target)r = mid;//改了这 
11     }
12     cout << mid << " " << a[mid];
13     return 0;
14 }

卡死循环了

打住打住,这六个案例已经能说明问题了:

只要输出在外面,怎么改都是错(包括把>改成>=,<改成<=)

所以,输出一定要放在循环里面!

比如这样:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 5     int l = 1,r = 20;
 6     int target,mid;target = 6; //目标值为6 
 7     while(l <= r){
 8         mid = (l+r+1)/2;
 9         if(a[mid] < target)l = mid+1;
10         else if(a[mid] > target)r = mid-1;
11         else{
12             cout << mid << " " << a[mid];
13             break;
14         }
15     }
16     
17     return 0;
18 }

 

或这样:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    int l = 1,r = 20;
    int target,mid;target = 6; //目标值为6 
    while(l <= r){
        mid = (l+r)/2;//改了这
        if(a[mid] < target)l = mid+1;
        else if(a[mid] > target)r = mid-1;
        else{
            cout << mid << " " << a[mid];
            break;
        }
    }
    
    return 0;
}


但是,这样不行:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    int l = 1,r = 20;
    int target,mid;target = 6; //目标值为6 
    while(l < r){//改了这
        mid = (l+r)/2;//和这
        if(a[mid] < target)l = mid+1;
        else if(a[mid] > target)r = mid-1;
        else{
            cout << mid << " " << a[mid];
            break;
        }
    }
    
    return 0;
}

 问题出在l == r,但是又没找到,所以没有输出

这样也不行:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main(){
 4     int a[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 5     int l = 1,r = 20;
 6     int target,mid;target = 6; //目标值为6 
 7     while(l <= r){
 8         mid = (l+r)/2;
 9         if(a[mid] <= target)l = mid+1;//改了这 
10         else if(a[mid] >= target)r = mid-1;//改了这 
11         else{
12             cout << mid << " " << a[mid];
13             break;
14         }
15     }
16     
17     return 0;
18 }

前面两个if和else if把情况全部囊括了,一点都不留给else,这能对吗?

除了这两个,其他的应该都是对的了,吧?(请各位帮我验证一下,结果写在评论区)