二分查找

			二分查找

也称折半查找,是一种在有序数组中查找某一特定元素的搜索算法。折半查找的查找过程为:从表的中间记录开始,如果给定值和中间记录的关键字相等,则查找成功;如果给定值大于或者小于中间记录的关键字,则在表中大于或小于中间记录的那一半中查找,这样重复操作,直到查找成功,或者在某一步中查找区间为空,则代表查找失败。
(1) 当所查找的元素重复出现时,则搜索结束后返回的下标不一定是第一次出现的位置。
比如 1 1 1 2 3,若查找1,则返回的下标是2。
比如 1 2 1 3 5,若查找1,则返回的下标是0。

  • 搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束。
  • 如果所查找元素大于中间元素,则low(数组起始下标)=mid+1,即在数大的一方查找。
  • 如果所查找元素小于中间元素,则high(数组末尾下标)=mid-1,即在数小的一方查找。
  • 代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int binsearch(int b,int a[],int n)
{
 int low=0,high=n-1,mid;
 while(low<=high)
 {
  mid=(low+high)/2;
  if(b<a[mid])
   high=mid-1;
  else if(b>a[mid])
   low=mid+1;
  else
   return mid;
 }
 return -1;
}
int main()
{
 int n,i,a[1000],b,w;
 printf("输入元素个数\n"); 
 scanf("%d",&n);
 printf("输入元素\n");
 for(i=0;i<n;i++)
  scanf("%d",&a[i]);
 sort(a,a+n);
 printf("输入查找元素\n");
 scanf("%d",&b);
 w=binsearch(b,a,n);
 if(w!=-1)
  printf("查找到该数位置下标为%d\n",w);
 else
  printf("没有查找到\n");
 return 0;
}

(2)搜索结束后返回的下标是该数第一次出现的位置。
比如 1 1 1 2 3,若查找1,则返回的下标是0。

  • 搜索过程从数组的中间元素开始,当不满足low<high条件时,搜索过程结束。
  • 如果所查找元素小于或者等于中间元素,则high=mid,即high的值减小,在数小的一方查找。
  • 如果所查找元素大于中间元素,则low=mid-1,即low值增大,在数大的一方查找。
  • 代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int n,a[1000];
int binsearch(int b)
{
 int low=0,high=n-1,mid;
 while(low<high)
 {
  mid=(low+high)/2;
  if(b<=a[mid])  
   high=mid;
  else
   low=mid+1;
 }
 return low;
}
int main()
{
 int i,b,w;
 printf("输入元素个数\n"); 
 scanf("%d",&n);
 printf("输入元素\n");
 for(i=0;i<n;i++)
  scanf("%d",&a[i]);
 sort(a,a+n);
 printf("输入查找元素\n");
 scanf("%d",&b);
 w=binsearch(b);
 if(a[w]==b)
  printf("查找到该数位置下标为:%d\n",w);
 else 
  printf("没有查找到\n");
 return 0;
}

(3)头文件algorithm里面包含lower_bound函数和upper_bound函数
格式:
lower_bound(a(起始位置) , a+n(结束位置), key(所要查找的值))-a
upper_bound(a(起始位置) , a+n(结束位置), key(所要查找的值))-a

※调用lower_bound和upper_bound之前必须确定序列为有序序列,否则调用出错。
※ 函数lower_bound()在数组的起始位置和结束位置中进行二分查找,返回大于或等于所查找元素第一次出现的下标。
如果所有元素都小于所查找元素,则返回最后一个元素的下一位的下标;如果所有元素都大于所查找元素,则返回第一个元素的下标。
※ 函数upper_bound( )在数组的起始位置和结束位置中进行二分查找,返回大于所查找元素第一次出现的下标,不存在则返回最后一个元素的下一位的下标。
※ 利用(upper_bound(a, a+n, key)-a)-(lower_bound(a, a+n, key)-a)可以计算所查找元素出现的次数。
※代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
 int n,a[100],i,b;
 printf("输入元素个数\n"); 
 scanf("%d",&n);
 printf("输入元素\n");
 for(i=0;i<n;i++)
  scanf("%d",&a[i]);
 sort(a,a+n);
 printf("输入查找元素\n");
 scanf("%d",&b);
 printf("返回a[i]中第一个大于等于b的下标:%d\n",lower_bound(a,a+n,b)-a);
 printf("返回a[i]中第一个大于b的下标:%d\n",upper_bound(a,a+n,b)-a);
 printf("输出所查找元素出现的次数:%d\n",(upper_bound(a,a+n,b)-a)-(lower_bound(a,a+n,b)-a));
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值