【C语言】编写函数实现二分查找

  问题:编写一个函数,实现二分查找(也叫折半查找)。
  实现思路:
  要实现二分查找函数,首先必须要有一个有序的整型数组;定义三个变量left,mid和right,分别作为数组下标用来访问数组的左中右位的元素。最开始时,left=0,right=sizeof(arr) / sizeof(arr[0]) - 1,mid=(left+right)>>1。将arr[mid]与要查找的元素进行比较,以不断调整left,right以及mid从而锁定新的区间进行新一轮的判断和调整(若某次arr[mid]等于目标元素,则直接返回该元素在数组中的下标,否则,继续比较,上述过程需要循环来完成)。若经过判断,仍未找到目标元素,则返回-1。
  图解:
  假设要查找的目标元素为key=7。
  ⑴初始状态:
  这里写图片描述
  ⑵经过比较,arr[mid]=5 < key=7,则说明目标元素在中间元素的右边,需将left重置为mid+1,right不变,此时则锁定了目标元素所在的新的区间,如下图中黑色区间:
  这里写图片描述
  ⑶由于left重置后为5,所以mid=(left+right)>>2=7:
  这里写图片描述
  ⑷经过比较,arr[mid]=8>key=7,则说明目标元素在中间元素的左边,需将right重置为mid-1,left不变,此时则锁定了目标元素所在的新的区间,如下图中紫色区间:
  这里写图片描述
  ⑸由于right重置后为6,所以mid=(left+right)>>2=5:
  这里写图片描述
  ⑹经过比较,arr[mid]=6 < key=7,则说明目标元素在中间元素的y右边,需将left重置为mid+1,right不变,而此时left=right=mid=6,如图:
  这里写图片描述
  ⑺经过比较,arr[mid]=key=7,找到了目标元素,则函数返回目标元素7的下标6。
  参考代码:

#include<stdio.h>
#include<stdlib.h>
int bin_search(int arr[], int left, int right, int key)
{
    int mid = 0;
    while (left < right)
    {
        mid = (left + right) >> 1;
        //mid = (left + right)/2
        if (arr[mid]>key)
        {
            right = mid - 1;
        }
        else if (arr[mid] < key)
        {
            left = mid + 1;
        }
        else
            return mid;//若找到,返回下标
    }
    return -1;//未找到
}
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int left = 0;
    int right = sizeof(arr) / sizeof(arr[0]) - 1;
    int ret = bin_search(arr, left, right, 5);//用ret接收函数的返回值
    printf("ret=%d\n", ret);
    system("pause");
    return 0;
}

  输出结果:
  这里写图片描述
  注意:
  ⑴left和right仅仅是用来计算mid和调整mid所在区间,以便于arr[mid]和目标元素比较。left,right和mid都是元素的下标。
  ⑵在主函数中调用二分查找函数时,需将实参(数组名,left,right,目标元素)的值传递给形参。
  ⑶当不断进行left,right和mid的调整后,若三者相等,还应进入循环进行判断,否则可能会永远找不到(而实际上目标元素是存在的),即循环执行的条件是left<=right,当left>right时,循环结束。
  

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值