侧边栏壁纸
博主头像
半生瓜のblog

THIS IS NO END.

  • 累计撰写 278 篇文章
  • 累计创建 3 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

C语言函数二分查找(折半查找)

xuanxuan
2020-12-06 / 0 评论 / 0 点赞 / 3 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-02-14,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

C语言函数二分查找(折半查找)

参考视频讲解哔哩哔哩比特鹏哥的视频 ——链接

////二分查找
#include <stdio.h>

    //二分查找
   //在一个有序数组中查找具体的某个数
    //如果找到了返回,这个数的下标,找不到返回-1

    //例如我要在这个数组中找到7
    //首先找到这组被查找元素的中间的元素
    //假如说发现中间元素5要比我要找的数要小
    //说明我要找的数在5的右边,这样我的范围就缩小了一半
    //查找了一次范围就缩小了一半,这样的速度是比较快的
    //这就叫二分查找(折半查找)
    //那么怎么找到中间元素的下标呢
    //原来的数组是1 2 3 4 5 6 7 8 9 10 
    //他们的下标是0 1 2 3 4 5 6 7 8 9
    //左下标为0,右下标为9
    //给定完这组元素的下标,就可以通过左右元素的下标来确定中间元素的下标
    //就是这组被查找元素的左下标是0,右下标是9
    //0和9的平均值是4,下标4锁定的元素是5,就可以认为5就是这组元素的中间元素了
    //5这个元素比我要找的7要小
    //说明我要被查找的元素范围就变成了6到10
    //新的范围,左下标是5,右下标是9
    //左右下标又可以求出一个平均值是7,又找到一个对应的元素是8
    //所以这一组查找范围的中间元素是8
    //用8再跟我要找的元素比一下,比我找的元素要大
    //说明我要查找的元素在8的左边
    //这时候要查找的范围被再次的缩小成了6到7

    //基本思想,当我确定了被查找范围时候,要确定他的左下标和右下标,然后求出下标的平均值,
    //找到中间元素,将中间元素和我要找的元素比一下,如果比我找的元素大,说明我要找的元素在他的左边,
    //如果比我要找的元素小,说明我要找的元素在他的右边,
    //这样确定出新的范围,出现新的左右下标。
    //一直找到左右下标无法确定新的范围,他们之间没有元素可以被查找的时候,结束,说明没有找到
    //如果在某一次查找的时候,找到了,下标相等了,说明找到了,把下标给过来

int number_search(int arr[], int k)
{
    //算法实现
    int sz = sizeof(arr) / sizeof(arr[0]);
    int left = 0;//左下标
    int right = sz - 1 ;//右下标
    //放到循环中
    while (left <= right)//这样才说明中间是有元素可以被查找的
    {
        int mid = (right + left) / 2;//中间元素的下标
        //拿到这个mid——锁定个元素
        if (arr[mid] < k)//如果中间元素比我要找的k要小,
                        //被查找范围的右下标不用变,左下标变成mid+!
        {
            left = mid + 1;
        }
        else if (arr[mid] > k)
        {
            right = mid - 1;
        }
        else
        {
            return mid;
        }
        //如果找不到
        return -1;//返回去了
    }
}

int main(void)
{

    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 7;
    int ret = number_search(arr, k);
    if (ret == -1)
    {
        printf("找不到指定的数字\n");
    }
    else
    {
        printf("找到了,下标是:%d\n",ret);
    }
    return 0;
}

//运行发现找不到结果——代码出现了问题
//自己找问题的方法
//部分位置添加注释后
 ////二分查找
#include <stdio.h>

int number_search(int arr[], int k)
//实际上这地方传递过来的数组arr是首元素地址
//本质上这里的arr是个指针,因为指针才可以接收地址
{
    //算法实现
    int sz = sizeof(arr) / sizeof(arr[0]);
    // 4/4=1  无法得到元素个数
    //sz出现了问题
    int left = 0;//左下标
    int right = sz - 1;//右下标
    //放到循环中
    while (left <= right)//这样才说明中间是有元素可以被查找的
    {
        int mid = (right + left) / 2;//中间元素的下标
        //拿到这个mid——锁定个元素
        if (arr[mid] < k)//如果中间元素比我要找的k要小,
                        //被查找范围的右下标不用变,左下标变成mid+!
        {
            left = mid + 1;
        }
        else if (arr[mid] > k)
        {
            right = mid - 1;
        }
        else
        {
            return mid;
        }
        //如果找不到
        return -1;//返回去了
    }
}

int main(void)
{

    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int k = 7;
    //只要把数组传参传过去
    //在内部是不能再上面的方式求元素个数了
    //数组是一块连续的空间,他里面可以放很多个元素
    //数组在传参的时候
    int ret = number_search(arr, k);//在这里仅仅传的是数组第一个元素的地址,不是所有元素
    if (ret == -1)
    {
        printf("找不到指定的数字\n");
    }
    else
    {
        printf("找到了,下标是:%d\n", ret);
    }
    return 0;
}

既然传进去不行,那就在外面算,

//修改版(注释已经删除)(只有修改后的注释)
////二分查找
#include <stdio.h>
//将多传递过来的参数sz接收
int number_search(int arr[], int k,int sz)
{
    int left = 0;
    int right = sz - 1 ;    
    //进入到这个循环中就是一次二分查找
    //在这里要进行很多次
    //每一次二分查找的第一步是找被查找范围的中间元素的下标
    while (left <= right)
    {
        int mid = (right + left) / 2;
        if (arr[mid] < k)
        {
            left = mid + 1;
        }
        else if (arr[mid] > k)
        {
            right = mid - 1;
        }
        else
        {
            return mid;
        }
    }
    return -1;
}
int main(void)
{   
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 7;
    //将计算元素个个数
    int sz = sizeof(arr) / sizeof(arr[0]);
    int ret = number_search(arr, k,sz);//将sz也传过去
    if (ret == -1)
    {
        printf("找不到指定的数字\n");
    }
    else
    {
        printf("找到了,下标是:%d\n",ret);
    }
    return 0;
}

正在学习ing

0

评论区