如果x>a[n/2],则我们只要在数组a的右半部继续搜索x。
二分搜索法的应用极其广泛,而且它的思想易于理解。
第一个二分搜索算法早在1946年就出现了,但是第一个完全正确的二分搜索算法直到1962年才出现。
Bentley在他的著作《WritingCorrectPrograms》中写道,90%的计算机专家不能在2小时内写出完全正确的二分搜索算法。
问题的关键在于准确地制定各次查找范围的边界以及终止条件的确定,正确地归纳奇偶数的各种情况,其实整理后可以发现它的具体算法是很直观的。
✧方法一:
直接查找
穷举法遍历
✧方法二:
递归查找
#include
#defineMAX30
intBinarySearch(inta[],int&x,intleft,intright)
{
if(left>right){
return-1;
}
else{
left=(left+right)/2;
if(x==a[left])
returnleft;
else
{
if(x>a[left])
BinarySearch(a,x,left+1,right);
else
BinarySearch(a,x,left*2-right,left+1);
}
}
}
main()
{
inta[MAX];
intfound,x,n,i,j,p;
printf("输的个数\n");
scanf("%d",&n);
printf("数组数据\n");
for(i=0;i{
scanf("%d",&a[i]);
}
for(i=0;i{
p=i;
for(j=i+1;jif(a[p]>a[j])
p=j;
if(p!
=j)
{
x=a[p];
a[p]=a[i];
a[i]=x;
}
}
for(i=0;i{
printf("%d",a[i]);
}
printf("输入要查找的数\n");
scanf("%d",&x);
found=BinarySearch(a,x,0,n);
if(found==-1)
{
printf("未找到\n");
}
else
{
printf("要查找的数在第%d个\n",found+1);
}
}
✧方法三:
迭代查找
#include
#defineMAX30
intBinarySearch(inta[],int&x,intn)
{
intleft=0;
intright=n-1;
intmiddle;
while(left<=right){
middle=(left+right)/2;
if(x==a[middle])
returnmiddle;
if(x>a[middle])
left=middle+1;
elseright=middle-1;
}
return-1;
}
main()
{
inta[MAX];
intfound,x,n,i,j,p;
printf("数的个数\n");
scanf("%d",&n);
printf("数组数据\n");
for(i=0;i{
scanf("%d",&a[i]);
}
for(i=0;i{
p=i;
for(j=i+1;jif(a[p]>a[j])
p=j;
if(p!
=j)
{
x=a[p];
a[p]=a[i];
a[i]=x;
}
}
for(i=0;i{
printf("%d",a[i]);
}
printf("输入要查找的数\n");
scanf("%d",&x);
found=BinarySearch(a,x,n);
if(found==-1)
{
printf("未找到\n");
}
else
{
printf("要查找的数在第%d个\n",found+1);
}
}
4.程序代码
变量定义说明:
BinarySearch()算法:
a->数组
key->要查找的元素
left->左标志
right->右标志
(n->数据个数)
Main()主函数:
ound->是否找到标志,-1表示未找到,找到其值为下标
x->要查找的元素
n->元素个数
i,j,p->循环控制变量
(1)、递归查找
#include
#defineMAX30
intBinarySearch(inta[],intkey,intleft,intright)
{
intmid=(right-right)/2+left;
if(a[mid]==key){
returnmid;
}
if(left>=right){
return-1;
}elseif(key>a[mid]){
returnBinarySearch(a,key,mid+1,right);
}elseif(keyreturnBinarySearch(a,key,left,mid-1);
}
return-1;
}
intmain(void)
{
inta[MAX];
intfound,x,n,i,j,p;
printf("数据个数:
");
scanf("%d",&n);
printf("输入数据:
\n");
for(i=0;i{
printf("请输入第%d个数据:
",i);
scanf("%d",&a[i]);
}
for(i=0;i{
p=i;
for(j=i+1;jif(a[p]>a[j])
p=j;
if(p!
=j)
{
x=a[p];
a[p]=a[i];
a[i]=x;
}
}
printf("排序后的数据如下:
");
for(i=0;i{
printf("%d",a[i]);
}
printf("\n");
printf("输入要查找的数:
");
scanf("%d",&x);
intleft=0,right=n;
found=BinarySearch(a,x,left,right);
if(found==-1)
{
printf("未找到\n");
}
else
{
printf("要查找的数在第%d个\n",found+1);
}
}
(2)、非递归查找
#include
#defineMAX30
intBinarySearch(inta[],intkey,intlen){
intmid=len/2;
if(key==a[mid]){
returnmid;
}
intleft=0;
intright=len-1;
while(left<=right){//迭代查找
mid=(right+left)/2;
if(keyright=mid-1;
}elseif(key>a[mid]){
left=mid+1;
}else{
returnmid;
}
}
return-1;
}
intmain(void)
{
inta[MAX];
intfound,x,n,i,j,p;
printf("数据个数:
");
scanf("%d",&n);
printf("输入数据:
\n");
for(i=0;i{
printf("请输入第%d个数据:
",i);
scanf("%d",&a[i]);
}
for(i=0;i{
p=i;
for(j=i+1;jif(a[p]>a[j])
p=j;
if(p!
=j)
{
x=a[p];
a[p]=a[i];
a[i]=x;
}
}
printf("排序后的数据如下:
");
for(i=0;i{
printf("%d",a[i]);
}
printf("\n");
printf("输入要查找的数:
");
scanf("%d",&x);
intleft=0,right=n;
found=BinarySearch(a,x,n);
if(found==-1)
{
printf("未找到\n");
}
else
{
printf("要查找的数在第%d个\n",found+1);
}
}
5.结果运行与分析
找到要查找的数据:
未找到要查找的数据:
六.心得与体会
通过这次实验,巩固了自己对二分搜索算法的理解,它是分治法的一个特殊例子,由此也对分治法有了更深一层次的认识。
分而治之,化复杂为简单,不只是在算法中,在日常生活中也是极其重要的。
正如Bentley在他的著作《WritingCorrectPrograms》中所说,能够完整的写出二分搜索算法是很难的,准确来说,在固定的时间内很大一部分人是不能完成这个任务的,因为其中的边界判定问题需要引起很大的注意,一不留神就容易犯错,导致结果的错误,而这种边界问题有很难找到,只有通过一步一步的演算才能完全正确的推导出来。
这告诫我们,熟能生巧,只有在生活中多练习,当真正需要的时候,才能够信手拈来。
欢迎您的下载,
资料仅供参考!
致力为企业和个人提供合同协议,策划案计划书,学习资料等等
打造全网一站式需求