二分查找(手写和自带函数)(从小到大的序列:第一个大于x的数/第一个大于等于x的数/第一个等于x的数/小于x的数中,最右边的数/小于等于x的数中,最右边的数 ; 从大到小的序列:第一个小于x的数/第一个小于等于x的数/第一个等于x的数/大于x的数中,最右边的数/大于等于x的数中,最右边的数)
1 /** 2 1. rightmost_smaller,那肯定是第一个啊。所以不成立! : 应该是小于x的数最靠右的那个 3 2. 两个方法,a. 手写二分while (l<r)... b.binary_search函数upper_bound和lower_bound。它们互相对照 4 3. 手写二分 5 (可以很容易回想起来的,容易记住的) 6 a. l+1 r-1 <= 为了能够可以退出 7 b. 数组是从0还是1开始的 sort(a,a+n) sort(a+1,a+n) 然后upper_bound这些,是对应指a/a+1后的第几个 8 c. 边界问题,怎么样才是没有找到:最后找到最右边结束也没找到 9 **/ 10 11 12 #include <cstdio> 13 #include <cstdlib> 14 #include <cstring> 15 #include <cmath> 16 #include <cstdbool> 17 #include <string> 18 #include <algorithm> 19 #include <iostream> 20 #include <sstream> 21 #include <ctime> 22 #include <stack> 23 #include <vector> 24 #include <queue> 25 #include <set> 26 #include <map> 27 using namespace std; 28 #define ll long long 29 #define ull unsigned long long 30 31 const ll mod_1=1e9+7; 32 const ll mod_2=998244353; 33 34 const double eps_1=1e-5; 35 const double eps_2=1e-10; 36 37 const int maxn=2e5+10; 38 39 //int a[maxn],n; 40 41 int n=10; 42 int a[11]={0,1,2,3,4,5,6,7,8,9,10}; 43 int a_rev[11]; 44 45 //0,1,1,2,2,2,3,4,4,5 46 47 /* 48 lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 49 50 upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 51 52 ———————————————— 53 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 54 55 原文链接:https://blog.csdn.net/qq_40160605/article/details/80150252 56 */ 57 58 /* 59 1.排序和建堆的效果 60 排序: 61 less<T>变成升序(从左到右遍历下标时,数组元素是从小到大) 62 greater<T>变成降序(从左到右遍历下标时,数组元素是从大到小) 63 建堆: 64 less<T>变成大顶堆(从上层到下层,堆元素是从大到小,同层之间随便) 65 greater<T>变成小顶堆(从上层到下层,堆元素是从小到大,同层之间随便) 66 可以看到排序和建队时,less和greater并不是直接对应汉语意思,不能统一。其实是真正的意思是两个要比较的元素,第一个元素是否比第二个元素更小less还是更大greater。 67 ———————————————— 68 69 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 70 71 原文链接:https://blog.csdn.net/sandalphon4869/article/details/105419706 72 */ 73 74 75 76 ///---------------/// 77 78 ///binary_search函数upper_bound和lower_bound 79 80 int way2_first_larger(int x) 81 { 82 ///从小到大的序列:第一个大于x的数 83 int index = upper_bound(a+1,a+n+1,x) - (a+1); 84 85 if (index==n) 86 return -1; 87 else 88 return index+1; 89 90 } 91 92 int way2_first_larger_than_or_equal(int x) 93 { 94 ///从小到大的序列:第一个大于等于x的数 95 int index = lower_bound(a+1,a+n+1,x) - (a+1); 96 97 if (index==n) 98 return -1; 99 else 100 return index+1; 101 } 102 103 int way2_first_equal(int x) 104 { 105 ///从小到大的序列:第一个等于x的数 106 int index = lower_bound(a+1,a+n+1,x) - (a+1); 107 if (index==n || a[index+1]!=x) 108 return -1; 109 else 110 return index+1; 111 } 112 113 int way2_rightmost_smaller(int x) 114 { 115 ///从小到大的序列:小于x的数中,最右边的数 116 int index = lower_bound(a+1,a+n+1,x) - (a+1); 117 if (index==0) 118 return -1; 119 else 120 return index; 121 } 122 123 int way2_rightmost_smaller_or_equal(int x) 124 { 125 ///从小到大的序列:小于等于x的数中,最右边的数 126 int index = upper_bound(a+1,a+n+1,x) - (a+1); 127 128 if (index==0) 129 return -1; 130 else 131 return index; 132 } 133 134 135 136 ///---------------/// 137 138 139 ///手写二分 140 141 int first_larger(int x) 142 { 143 ///从小到大的序列:第一个大于x的数 144 145 int l,r,mid; 146 l=1; 147 r=n; 148 149 while (l<=r) 150 { 151 mid=(l+r)/2; 152 153 //如果没有实现,改为要到实现 154 if (a[mid]<=x) 155 l=mid+1; 156 else 157 r=mid-1; 158 } 159 160 if (l==n+1) 161 return -1; 162 else 163 return l; 164 } 165 166 167 int first_larger_than_or_equal(int x) 168 { 169 ///从小到大的序列:第一个大于等于x的数 170 171 int l,r,mid; 172 l=1; 173 r=n; 174 175 while (l<=r) 176 { 177 mid=(l+r)/2; 178 179 //如果没有实现,改为要到实现 180 if (a[mid]<x) 181 l=mid+1; 182 else 183 r=mid-1; 184 } 185 186 if (l==n+1) 187 return -1; 188 else 189 return l; 190 } 191 192 int first_equal(int x) 193 { 194 ///从小到大的序列:第一个等于x的数 195 196 int l,r,mid; 197 l=1; 198 r=n; 199 200 while (l<=r) 201 { 202 mid=(l+r)/2; 203 204 //如果没有实现,改为要到实现 205 if (a[mid]<x) 206 l=mid+1; 207 else 208 r=mid-1; 209 } 210 211 if (l==n+1 || a[l]!=x) 212 return -1; 213 else 214 return l; 215 } 216 217 218 int rightmost_smaller(int x) 219 { 220 ///从小到大的序列:小于x的数中,最右边的数 221 ///大于等于x的数,它的最早第一个数 222 223 int l,r,mid; 224 l=1; 225 r=n; 226 227 while (l<=r) 228 { 229 mid=(l+r)/2; 230 231 //如果没有实现,改为要到实现 232 if (a[mid]<x) 233 l=mid+1; 234 else 235 r=mid-1; 236 } 237 238 if (r==0) 239 return -1; 240 else 241 return l-1; 242 } 243 244 int rightmost_smaller_or_equal(int x) 245 { 246 ///从小到大的序列:小于等于x的数中,最右边的数 247 ///大于x的数,它的最早第一个数 248 249 int l,r,mid; 250 l=1; 251 r=n; 252 253 while (l<=r) 254 { 255 mid=(l+r)/2; 256 257 //如果没有实现,改为要到实现 258 if (a[mid]<=x) 259 l=mid+1; 260 else 261 r=mid-1; 262 } 263 264 if (r==0) 265 return -1; 266 else 267 return l-1; 268 } 269 270 271 272 ///---------------/// 273 274 ///binary_search函数upper_bound和lower_bound 275 276 //descending 277 int des_way2_first_smaller(int x) 278 { 279 ///从大到小的序列:第一个小于x的数 280 int index = upper_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1); 281 282 if (index==n) 283 return -1; 284 else 285 return index+1; 286 } 287 288 int des_way2_first_smaller_than_or_equal(int x) 289 { 290 ///从大到小的序列:第一个小于等于x的数 291 int index = lower_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1); 292 293 if (index==n) 294 return -1; 295 else 296 return index+1; 297 } 298 299 int des_way2_first_equal(int x) 300 { 301 ///从大到小的序列:第一个等于x的数 302 int index = lower_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1); 303 304 if (index==n || a_rev[index+1]!=x) 305 return -1; 306 else 307 return index+1; 308 } 309 310 int des_way2_rightmost_larger(int x) 311 { 312 ///从大到小的序列:大于x的数中,最右边的数 313 int index = lower_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1); 314 315 if (index==0) 316 return -1; 317 else 318 return index; 319 } 320 321 int des_way2_rightmost_larger_than_or_equal(int x) 322 { 323 ///从大到小的序列:大于等于x的数中,最右边的数 324 int index = upper_bound(a_rev+1,a_rev+n+1,x,greater<>()) - (a_rev+1); 325 326 if (index==0) 327 return -1; 328 else 329 return index; 330 } 331 332 333 334 335 336 337 338 339 340 341 int main() 342 { 343 /** 344 针对 int n=10; int a[11]={0,1,2,3,4,5,6,7,8,9,10}; 345 **/ 346 347 if (0) 348 { 349 printf("%d\n", way2_first_larger(-100) ); //1 350 printf("%d\n", way2_first_larger_than_or_equal(-100) ); //1 351 352 printf("%d\n", way2_first_larger(100) ); //-1 353 printf("%d\n", way2_first_larger_than_or_equal(100) ); //-1 354 355 printf("%d\n", way2_first_larger(1) ); //2 356 printf("%d\n", way2_first_larger_than_or_equal(1) ); //1 357 358 printf("%d\n", way2_first_larger(10) ); //-1 359 printf("%d\n", way2_first_larger_than_or_equal(10) ); //10 360 361 printf("%d\n", way2_first_larger(5) ); //6 362 printf("%d\n", way2_first_larger_than_or_equal(5) ); //5 363 364 365 printf("\n---\n\n"); 366 367 368 printf("%d\n", way2_first_equal(-100) ); //-1 369 printf("%d\n", way2_first_equal(100) ); //-1 370 printf("%d\n", way2_first_equal(4) ); //4 371 372 373 printf("\n---\n\n"); 374 375 376 printf("%d\n", way2_rightmost_smaller(-100) ); //-1 377 printf("%d\n", way2_rightmost_smaller_or_equal(-100) ); //-1 378 379 printf("%d\n", way2_rightmost_smaller(100) ); //10 380 printf("%d\n", way2_rightmost_smaller_or_equal(100) ); //10 381 382 printf("%d\n", way2_rightmost_smaller(1) ); //-1 383 printf("%d\n", way2_rightmost_smaller_or_equal(1) ); //1 384 385 printf("%d\n", way2_rightmost_smaller(10) ); //9 386 printf("%d\n", way2_rightmost_smaller_or_equal(10) ); //10 387 388 printf("%d\n", way2_rightmost_smaller(5) ); //4 389 printf("%d\n", way2_rightmost_smaller_or_equal(5) ); //5 390 391 printf("%d\n", way2_rightmost_smaller(2) ); //1 392 printf("%d\n", way2_rightmost_smaller_or_equal(2) ); //2 393 394 } 395 396 397 398 if (0) 399 { 400 printf("%d\n", first_larger(-100) ); //1 401 printf("%d\n", first_larger_than_or_equal(-100) ); //1 402 403 printf("%d\n", first_larger(100) ); //-1 404 printf("%d\n", first_larger_than_or_equal(100) ); //-1 405 406 printf("%d\n", first_larger(1) ); //2 407 printf("%d\n", first_larger_than_or_equal(1) ); //1 408 409 printf("%d\n", first_larger(10) ); //-1 410 printf("%d\n", first_larger_than_or_equal(10) ); //10 411 412 printf("%d\n", first_larger(5) ); //6 413 printf("%d\n", first_larger_than_or_equal(5) ); //5 414 415 416 printf("\n---\n\n"); 417 418 419 printf("%d\n", first_equal(-100) ); //-1 420 printf("%d\n", first_equal(100) ); //-1 421 printf("%d\n", first_equal(4) ); //4 422 423 424 printf("\n---\n\n"); 425 426 427 printf("%d\n", rightmost_smaller(-100) ); //-1 428 printf("%d\n", rightmost_smaller_or_equal(-100) ); //-1 429 430 printf("%d\n", rightmost_smaller(100) ); //10 431 printf("%d\n", rightmost_smaller_or_equal(100) ); //10 432 433 printf("%d\n", rightmost_smaller(1) ); //-1 434 printf("%d\n", rightmost_smaller_or_equal(1) ); //1 435 436 printf("%d\n", rightmost_smaller(10) ); //9 437 printf("%d\n", rightmost_smaller_or_equal(10) ); //10 438 439 printf("%d\n", rightmost_smaller(5) ); //4 440 printf("%d\n", rightmost_smaller_or_equal(5) ); //5 441 442 printf("%d\n", rightmost_smaller(2) ); //1 443 printf("%d\n", rightmost_smaller_or_equal(2) ); //2 444 445 } 446 447 448 449 if (0) 450 { 451 copy(a+1, a+n+1, a_rev+1); 452 reverse(a_rev+1, a_rev+n+1); 453 454 printf("%d\n", des_way2_first_smaller(-100) ); //-1 455 printf("%d\n", des_way2_first_smaller_than_or_equal(-100) ); //-1 456 457 printf("%d\n", des_way2_first_smaller(100) ); //1 458 printf("%d\n", des_way2_first_smaller_than_or_equal(100) ); //1 459 460 printf("%d\n", des_way2_first_smaller(1) ); //-1 461 printf("%d\n", des_way2_first_smaller_than_or_equal(1) ); //10 462 463 printf("%d\n", des_way2_first_smaller(10) ); //2 464 printf("%d\n", des_way2_first_smaller_than_or_equal(10) ); //1 465 466 printf("%d\n", des_way2_first_smaller(2) ); //10 467 printf("%d\n", des_way2_first_smaller_than_or_equal(2) ); //9 468 469 printf("%d\n", des_way2_first_smaller(7) ); //5 470 printf("%d\n", des_way2_first_smaller_than_or_equal(7) ); //4 471 472 473 printf("\n---\n\n"); 474 475 476 printf("%d\n", des_way2_first_equal(-100) ); //-1 477 printf("%d\n", des_way2_first_equal(100) ); //-1 478 479 printf("%d\n", des_way2_first_equal(1) ); //10 480 printf("%d\n", des_way2_first_equal(10) ); //1 481 482 printf("%d\n", des_way2_first_equal(7) ); //4 483 484 485 printf("\n---\n\n"); 486 487 488 printf("%d\n", des_way2_rightmost_larger(-100) ); //10 489 printf("%d\n", des_way2_rightmost_larger_than_or_equal(-100) ); //10 490 491 printf("%d\n", des_way2_rightmost_larger(100) ); //-1 492 printf("%d\n", des_way2_rightmost_larger_than_or_equal(100) ); //-1 493 494 printf("%d\n", des_way2_rightmost_larger(1) ); //9 495 printf("%d\n", des_way2_rightmost_larger_than_or_equal(1) ); //10 496 497 printf("%d\n", des_way2_rightmost_larger(10) ); //-1 498 printf("%d\n", des_way2_rightmost_larger_than_or_equal(10) ); //1 499 500 printf("%d\n", des_way2_rightmost_larger(2) ); //8 501 printf("%d\n", des_way2_rightmost_larger_than_or_equal(2) ); //9 502 503 printf("%d\n", des_way2_rightmost_larger(7) ); //3 504 printf("%d\n", des_way2_rightmost_larger_than_or_equal(7) ); //4 505 } 506 507 508 509 510 511 return 0; 512 }
过去的:二分查找(等于x,小于x,小于等于x,大于x,大于等于x ) - congmingyige - 博客园 (cnblogs.com)