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,这能对吗?
除了这两个,其他的应该都是对的了,吧?(请各位帮我验证一下,结果写在评论区)
浙公网安备 33010602011771号