C语言—二分查找(折半查找)

写在前面:

实现二分查找的条件:1、要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。通俗来说所查找的数列或内容逻辑上必须有序。2、查找的数量是一个而不是多个

基本思路:1、定义一维数组a储存有序数据,left、right分别为第一个(左)和最后一个数组元素的下标。数组取值对应的是下标,数组的第一个下标是从0开始,那么右下标为元素个数-1。

2、循环入口判断left是否大于right。由于left一直在增加,而right一直在减少,直到最终查找出元素,若left <=right且未查找出指定元素时,循环继续进行。如果大于,则退出循环。

3、若目标值key大于a[mid],说明key比a[mid]左边的值都要大,下一次循环舍去左边的值left=mid+1;同理,如果key小于a[mid],说明key小于a[mid]右边的所有值,统统舍去right=mid-1。直到key=a[mid]或者left>right循环结束。

示例:设某数组里面的元素个数为{1,2,3,4,5,6,7,8,9},所查找的数为7。

第一次查找 mid=(left+right)/2 mid==下标为4对应元素5 小于我们查找的数那么把中间下标加一之后赋值给left==下标为4+1;右下标不变。此时没查找的元素为5 6 7 8 9

第二次查找 mid=(left+right)/2 mid==下标为7对应元素8 大于我们查找的数那么把中间下标减一之后赋值给right==下标为7-1,那么此时查找的范围为 下标为5 6的数

第三次查找 mid=(left+right)/2 mid==下标为5 小于我们查找的数那么把中间下标加一之后赋值给left==下标为5+1;

第四次查找 mid=(left+right)/2 mid==下标为6对应元素7

代码:

#include<stdio.h>
void binarysearch(int *a,int sum,int n)
{
    int left=0,mid=0,count=0;
    int right=sum-1;
    int key=n; // 对最小数组下标,最大下标,目标值,中间值,以及计数器的声明
    while(left<=right){
        count++;
        mid=(left+right)/2;
        if(key>a[mid])
            left=mid+1;  //
        else if(key<a[mid])
            right=mid-1;
        else if(key==a[mid]){
            printf("Success!\nAfter %d tries\na[%d]=%d",count,mid,key); 
            return ;
        }
    }
    printf("No found");
}
int main(void)
{
    int a[10]={1,2,3,4,5,6,7,8,9,10};
    printf("请输入你想要查找的数字\n");
    int n;
    scanf("%d",&n);
    binarysearch(a,10,n);
} 

注意:

1)计算 mid 时 ,最好不使用 (left + right )/ 2,建议使用mid = left + (right - left) / 2否则有可能会导致溢出;

2)while (left < = right) { } 注意括号内为 left <= right ,而不是 left < right ,如果我们设置条件为 left < right 则当我们执行到最后一步时,则我们的 left 和 right 重叠时,则会跳出循环,返回 -1,区间内不存在该元素,但 left 和 right 此时指向的可能就是目标元素 ;

3)left = mid + 1,right = mid - 1 而不是 left = mid 和 right = mid。否则可能会进入死循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值