二分查找——“C”

简介: 二分查找——“C”

各位CSDN的uu们你们好呀,欢迎来到小雅兰的课堂,今天我们的内容是复习之前的内容,并把之前的内容的一些习题一起来做一做,现在,就让我们进入二分查找的世界吧


首先,我们介绍的题目就是二分查找,也叫折半查找


我们定义了一个整型数组,为1 2 3 4 5 6 7 8 9 10,这个数组所有元素的下标为0 1 2 3 4 5 6 7 8 9,然后定义下标为0的元素为left,定义下标为9的元素为right,中间元素为mid

image.png

我们先假设要查找的元素就是7,那么就可以写出这样一个式子:mid=(left+right)/2;然后再进行二分查找,由下图可知,用二分查找的方式找到7这个元素最多只需要查找4次这样的效率远比遍历的方法的效率要高

image.png

image.png


下面,我们来用代码来实现一下此功能吧

#include<stdio.h>
int main()
{
   int arr[]={1,2,3,4,5,6,7,8,9,10};
            //0,1,2,3,4,5,6,7,8,9
   int k=7;//k是要查找的数字
   int sz=sizeof(arr)/sizeof(arr[0]);
   //折半查找(二分查找),前提是数组有序
   int left=0;
   int right=sz-1;
   int flag=0;//一个标记变量
   while(left<=right)
   {
      int mid=(left+right)/2;
      if(arr[mid]<k)
      {
         left=mid+1;
      }
      else if(arr[mid]>k)
      {
         right=mid-1;
      }
      else
      {
         printf("找到了,下标是:%d\n",mid);
         flag=1;
         break;
      }
   }
   if(flag==0)
   {
      printf("找不到\n");
   }
   return 0;
}

然后,我们来运行一些此代码

image.png

写到这里,我们不禁会想起一个问题:如果这个数组非常非常大怎么办?


如果这个数组非常非常大,left和right非常大,left没有超出整型范围的最大值,right也没有超过整型范围的最大值,但left+right的和超出了整形范围的最大值,就会造成溢出现象,溢出之后的数据再除以2,就不是平均值了,所以mid=(left+right)/2这样的写法还是存在潜在风险


我们可以这样写:mid=left+(right-left)/2;


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
                //0,1,2,3,4,5,6,7,8,9
    int k = 7;//k是要查找的数字
    scanf("%d", &k);
    int sz = sizeof(arr) / sizeof(arr[0]);
    //折半查找(二分查找),前提是数组有序
    int left = 0;
    int right = sz - 1;
    int flag = 0;//一个标记变量
    while (left <= right)
    {
        int 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);
            flag = 1;
            break;
        }
    }
    if (flag == 0)
    {
        printf("找不到\n");
    }
    return 0;
}

最后的结果也是非常正确的


image.png

我们再来研究研究,前段时间我们学习了“函数”这一知识点,那我们也是可以封装一个函数来实现此代码的,那好吧,一起来实操一下

#include<stdio.h>
int binary_search(int arr[],int k,int sz)
{
   int left=0;
   int right=sz-1;
   while(left<=right)
   {
      int mid=left+(right-left)/2;
      if(arr[mid]>k)
      {
         right=mid-1;
      }
      else if(arr[mid]<k)
      {
         left=mid+1;
      }
      else
      {
         return mid;
      }
   }
   return -1;
}
int main()
{
   int arr[]={1,2,3,4,5,6,7,8,9,10};
   int k=0;
   scanf("%d",&k);
   int sz=sizeof(arr)/sizeof(arr[0]);
   //找到了就返回下标,找不到就返回-1
   int ret=binary_search(arr,k,sz);
   if(ret==-1)
   {
      printf("找不到\n");
   }
   else
   {
      printf("找到了,下标是:%d\n",ret);
   }
   return 0;
}

好啦,用封装函数的方法也实现啦

image.png

那么,可能又会有人突发奇想,说:“可不可以把sz放在函数内部来求呢?”这个答案当然是否定

它的代码是这个样子

#include<stdio.h>
int binary_search(int arr[], int k)
{
    int left = 0;
    int sz = sizeof(arr) / sizeof(arr[0]);
    int right = sz - 1;
    while (left <= right)
    {
        int mid = left + (right - left) / 2;
        if (arr[mid] > k)
        {
            right = mid - 1;
        }
        else if (arr[mid] < k)
        {
            left = mid + 1;
        }
        else
        {
            return mid;
        }
    }
    return -1;
}
int main()
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 0;
    scanf("%d", &k);
    //找到了就返回下标,找不到就返回-1
    int ret = binary_search(arr, k);
    if (ret == -1)
    {
        printf("找不到\n");
    }
    else
    {
        printf("找到了,下标是:%d\n", ret);
    }
    return 0;
}

你运行起来,会发现,无论输入2之后的任意数字,输出的结果都是找不到

image.png

image.png

因为:arr是数组名,进行函数传参的时候,传进来的是首元素的地址,在binary_search()函数的形参中,arr实质上是一个指针,sizeof(arr)只是算出来这个首元素的地址所占空间大小,sizeof(arr[0])是这个元素占的空间大小,两者相除必为1.


而在主函数中求sz,sizeod(数组名) 计算的是整个数组的大小


   sizeof内部单独放一个数组名,数组名表示整个数组


好啦,小雅兰今天的内容就到这里啦,今天的内容可能比较简单,也很少,但是小雅兰有认真在学噢!!!uu们加油呀


相关文章
|
算法
【算法专题突破】二分查找 - 704. 二分查找(16)
【算法专题突破】二分查找 - 704. 二分查找(16)
38 0
|
算法 索引
二分查找(详解)
二分查找(详解)
|
7月前
|
算法 索引
二分查找(一)
二分查找(一)
|
7月前
|
算法 索引
二分查找(二)
二分查找(二)
|
7月前
|
算法 C++
C++021-C++二分查找
C++021-C++二分查找
C++021-C++二分查找
|
算法 C语言
这就是二分查找?
本文通过简单的猜数字小游戏向大家介绍二分查找的基本原理。
126 2
|
算法 索引
【二分查找】
【二分查找】
|
存储 算法
6-2 二分查找
6-2 二分查找
173 0
下一篇
DataWorks