二分查找

1.binary searching:

二分查找的前提是,数组中的元素已经排好序。假设数组升序排列。二分查找首先将关键字和数组的中间元素进行比较。

1)如果关键字等于中间元素,则匹配成功,查找结束。

2)如果关键字小于中间元素,则在前一半中继续查找。

3)如果关键字大于中间元素,则在后一半中继续查找。

每次查找都是排除一半或者一半加1个元素。为了方便起见,假设数组元素n个,且n为2的幂。假设最坏情况,查找直到剩下一个元素才结束。查找第一次,就剩下n/2个,第二次n/2/2,经过k次,剩下一个元素。n/2/2/2...=1;显然,k=log2(n);于是,再将关键字与最后这个数值作比较,也就是需要log2(n)+1次比较。

如果目标值不在序列中,二分查找将会清空搜索空间。

问题的关键是是如何实现重复地查找。

关于low<=high。查找,就是元素比较,若key在数组中,则通过不断取中间值能得到结果,如果不在其中,则最终将key逼近在两个相邻元素之间,那么此时就要接近结束循环,low=high-1,如果key就是high下标对应值,low<high,则提前终止,不符合要求。

关于-low-1返回值,表示如果不在其中,则应该插入的下标是low。其中-1是为了区分插入首个位置。-0=0,无法区分在还是不在数组中。

=============code===============

#include<stdio.h>
int binary_search(int arr[],int key,int len)
{
int low=0,high=len-1;
while(low<=high) 
{
int mid=low+(high-low)/2;
if(key==arr[mid]) return mid;
else if(key>arr[mid]) low=mid+1;
else high=mid-1;
}
return -low-1;
}
int main()
{
int arr[]={1,3,5,7,9,11,34,56,56,56,78,99,111};
int key,len;
scanf("%d",&key);
len=sizeof(arr)/sizeof(int);
printf("%d\n",binary_search(arr,key,len));
return 0;
}

=============code===============

2.在有重复的数组中,查找第一个(最后一个)key的下标

如果key在其中,先查找到一个,flag标记一定存在key,此时不再马上return,而是继续在【0,mid-1】查找,一直到找不到为止,并保存好上一刻mid的值,以免【0,mid-1】中不存在key,丢失mid下标

=============code===============

#include<stdio.h>
int binary_search(int arr[],int key,int len)
{
int low=0,high=len-1,mid_prev,flag=0;
while(low<=high) 
{
int mid=low+(high-low)/2;
if(key==arr[mid]) mid_prev=mid,low=0,high=mid-1,flag=1;
else if(key>arr[mid]) low=mid+1;
else high=mid-1;
}

if(flag!=0) return mid_prev;

else return -low-1;
}
int main()
{
int arr[]={1,3,5,7,9,11,34,56,56,56,78,99,111};
int key,len;
scanf("%d",&key);
len=sizeof(arr)/sizeof(int);
printf("%d\n",binary_search(arr,key,len));
return 0;
}

=============code===============

3.在有序数组中,查找重复元素key的个数

在有重复的数组中,查找第一个key的下标,在有重复的数组中,查找最后一个key的下标,相减+1即可。

在有重复的数组中,查找(最后一个)key的下标code
=============code===============

#include<stdio.h>
int binary_search(int arr[],int key,int len)
{
int low=0,high=len-1,mid_prev,flag=0;
while(low<=high) 
{
int mid=low+(high-low)/2;
if(key==arr[mid]) mid_prev=mid,low=mid+1,high=len-1,flag=1;
else if(key>arr[mid]) low=mid+1;
else high=mid-1;
}

if(flag!=0) return mid_prev;

else return -low-1;
}
int main()
{
int arr[]={1,3,5,7,9,11,34,56,56,56,78,99,111};
int key,len;
scanf("%d",&key);
len=sizeof(arr)/sizeof(int);
printf("%d\n",binary_search(arr,key,len));
return 0;
}

=============code===============

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值