有序数列的二分查找问题

有序数列的二分查找问题

二分查找也叫折半查找,它是一种比较高效的查找方法,相比于顺序查找O(n)的时间复杂度来说,其时间复杂度O(log2n)占很明显的优势。

但是并不是所有的数列都可以用二分查找的方法,二分查找要求所给的数列必须是有序的,即是按顺序结构在计算机中存储的,并且必须按关键字的大小有序排列。以整型数据为例,找到了返回该元素的下标,下面来介绍具体的实现方法:

在此之前,我们需要将有序的一组数据存储到数组中,创建arr数组来存放若干个要存放的有序数,我们要将数组折半,就需要得到数组中间元素的下标,要知道中间元素的下标,我们就得知道数组最左边元素的下标和最右边元素的下标,设左下标为 left ,右下标为 right ,显然 left =0 , right =数组元素个数 - 1,数组元素个数 sz = sizeof(arr) / sizeof(arr[0]) ,我们再取左右下标的平均值为中间下标 mid ,万事俱备,接下来进行下一步操作。

首先,我们得到 mid = (left + right) ,将数组下标为 mid 的元素与要查找的数 k 进行比较:
1、arr[mid] < k
中间元素小于要查找的数,说明要查找的数在中间数的右边,所以中间数左边的内容可以舍弃,此时取中间下标右边的数组为下一轮要操作的数组, 令 left = mid +1 , right 不变。

2、 arr[mid] > k
中间元素大于要查找的数,说明要查找的数在中间数的左边,所以中间数右边的内容可以舍弃,此时取中间下标左边的数组为下一轮要操作的数组,令 right = mid - 1, left 不变。

3、 arr[mid] = k
此时 k 被找到, mid 即为其下标。

上面的操作只是一轮,当 leftright 不停的在变化,此时就需要循环,当 left < right 时,循环是可以执行的,但是我们要注意,在执行最后一次循环时,可能会出现 left = right =mid 的情况,所以循环条件应该为 left <= right

若跳出了循环还没有找到 k ,则数组里找不到这个数。

#include<stdio.h>
int main()
{
    
    
   int k=7;  //要查找的数字
   int arr[]={
    
    1,2,3,4,5,6,7,8,9,10};
   int left,mid,right;
   int sz = sizeof(arr)/sizeof(arr[0]);
   left = 0;
   right = sz -1;
   while(left<=right)
   {
    
    
      //mid = (left+right)/2;  可能会有溢出风险
      mid = left + (right - left)/2;
      if(arr[mid] < k)
      {
    
    
         left = mid +1;
      }
      else if(arr[mid] > k)
      {
    
    
         right = mid -1;
      }
      else
      {
    
    
         printf("找到了,下标是%d\n",mid);
      }
   }
   if(left > right)
   {
    
    
      printf("找不到\n");
      break;
   }
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_52606524/article/details/112800207
今日推荐