当前位置:   article > 正文

二分查找_二分查找最坏情况下比较次数

二分查找最坏情况下比较次数
二分查找
===================================================
1、原理
将数组以中间值为中心,一分为二;

要找的值--等于中间值则直接返回;小于中间值,则从中间值左边找;大于中间值,则从中间值右边找;

循环直到找到要找的值为止。

前提:二分查找的前提是需要查找的数组必须是已排序的,我们这里的实现默认为升序。

2java代码实现

可以用循环和递归两种方式实现。

  1. /**
  2. * 二分查找
  3. */
  4. public class BinarySearch {
  5. /**
  6. * 循环二分查找,返回第一次出现该值的位置
  7. * @param sortedData 已排序的数组
  8. * @param findValue 需要找的值
  9. * @return 值在数组中的位置,从0开始。找不到返回-1
  10. */
  11. public static int searchLoop(int[] sortedData, int findValue){
  12. int start = 0;
  13. int end = sortedData.length - 1;
  14. while(start<=end && (start<=sortedData.length-1) && (end<=sortedData.length-1)){
  15. int middleIndex = (start+end) >> 1; //中间位置,相当于(start+end)/2
  16. int middleValue = sortedData[middleIndex]; //中间值
  17. if(findValue == middleValue){
  18. return middleIndex; //等于中值,直接返回
  19. }else if(findValue < middleValue){
  20. //小于中值时在中值前面找:start还是0,end改为中间值的前一个middleIndex - 1
  21. end = middleIndex - 1;
  22. }else{
  23. //大于中值在中值后面找:end还是sortedDate.length-1,start为中间值的后一个moddleIndex+1
  24. start = middleIndex + 1;
  25. }
  26. }
  27. return -1; //找不到,返回-1
  28. }
  29. /**
  30. * 递归二分查找,返回第一次出现该值的位置
  31. * @param sortedData 已排序的数组
  32. * @param findValue 需要找的值
  33. * @return 值在数组中的位置,从0开始。找不到返回-1
  34. */
  35. public static int searchRecursive(int[] sortedData, int findValue, int start, int end){
  36. if(start <= end){
  37. int middleindex = (start+end) >> 1; //中间位置,相当于(start+end)/2
  38. int middleValue = sortedData[middleindex]; //中间值
  39. if(findValue == middleValue){
  40. return middleindex; //等于中值直接返回
  41. }else if(findValue < middleValue){ //小于中值时在中值前面找
  42. return searchRecursive(sortedData,findValue,start,middleindex-1);
  43. }else{ //大于中值在中值后面找
  44. return searchRecursive(sortedData,findValue,middleindex+1,end);
  45. }
  46. }
  47. return -1;
  48. }
  49. /**
  50. * test
  51. * @param args
  52. */
  53. public static void main(String[] args) {
  54. int[] sortedData = {1,2,3,4,5,6,6,7,8,8,9,10};
  55. //1.循环二分法查找
  56. int pos1 = searchLoop(sortedData, 12);
  57. System.out.println("循环二分法查找:" + pos1);
  58. //2.递归二分法查找
  59. int pos2 = searchRecursive(sortedData, 12, 0, sortedData.length-1);
  60. System.out.println("递归二分法查找:" + pos2);
  61. }
  62. }

3、时间复杂度

比如:总共有n个元素,每次查找的区间大小就是n,n/2,n/4,…,n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数。
由于n/2^k取整后>=1,即令n/2^k=1,
可得k=log2n,(是以2为底,n的对数),所以时间复杂度可以表示O()=O(logn)

(--更好理解)假设其数组长度为n,经过m次二分查找到结果(即只剩下一个元素),则:n/(2^m) = 1(即n=m^2)。

其算法复杂度为o(log(n))


最大查找次数:

二分查找因为每次都是从中间点开始查找,所以最大查找次数(最坏情况)是目标元素存在于最边缘的情况。比如1~9,最坏情况就是1或者9,当然4,6这种也算是边缘(中心的边缘)。

所以不难发现:
最多比较1次的串长是1
最多比较2次的串长是2-3
3是4-7
4是8-15
x是2^(x-1)-2^x-1

最坏情况下次数:logN+1(logN向下取整



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

闽ICP备14008679号