当前位置:   article > 正文

【C语言-二分法】二分法查找有序数组中数的下标为什么要mid+1,mid-1?_为什么二分法要left=mid+1,right=mid-1

为什么二分法要left=mid+1,right=mid-1

首先贴上整体代码:

  1. #include<stdio.h>
  2. int two_search(int arr[], int length, int k)
  3. {
  4. int left = 0;
  5. int right = length - 1;
  6. while (left <= right)
  7. {
  8. int mid = (right + left) / 2; //(0+9)/2=4
  9. if (k > arr[mid])
  10. left = mid+1; //加1 减1 是必须的
  11. else if (k < arr[mid])
  12. right = mid-1;
  13. else
  14. return mid;
  15. }
  16. return -1;
  17. }
  18. int main()
  19. {
  20. int arr[] = {1,2,3,4,5,6,7,8,9,10};
  21. int k = 11; //想查找的数的下标
  22. int length = sizeof(arr) / sizeof(arr[0]);
  23. int ret = two_search(arr,length,k);
  24. if (ret != -1)
  25. printf("找到,%d在数组中的下标为%d", k, ret);
  26. else
  27. printf("未找到");
  28. return 0;
  29. }

问题:这里的mid为什么要加1?

  1. while (left <= right)
  2. {
  3. int mid = (right + left) / 2; //(0+9)/2=4
  4. if (k > arr[mid])
  5. left = mid+1; //加1 减1 是必须的
  6. else if (k < arr[mid])
  7. right = mid-1;
  8. else
  9. return mid;
  10. }

分析:

当mid不使用加1操作时:

例如从 12345678910中查找8,结果是正确的:

当要查找11的时候,就出问题了: 

显然结果是查找不到,但是程序一直在运行,不能退出。

原因:

left会一直向右边靠拢,一直到left=8,此时right=9,mid=(8+9)/2=8,如此left一直是8,同时注意到循环体的成立条件while (left <= right),left 始终小于right,这样程序就无法跳出循环,造成死循环。如图:

 当mid使用加1操作时:

left会一直向右边靠拢,一直到left=8,此时right=9,mid=(8+9)=8进一步更新,使得left=mid+1=9,然后直到left越过right,使得while()不成立,从而跳出循环体。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/388741
推荐阅读
相关标签
  

闽ICP备14008679号