关于折半查找算法

二月底的末唤来了阳春三月的暖,天清气朗,惠风和煦,有时候真想拿着以前放的风筝,冲出去体验一把田野奔跑的欢乐。但也只是想想而已,越来越宅的我始终也离不开手中的笔记本电脑了。
也不知道是气温上升的缘故还是春困突然上头的缘故,看了几天的折半查找算法才算是把它搞懂。
折半查找算法是一种比顺序查找更高效简洁的算法,其查找长度至多为㏒2n+1(判定树的深度),平均查找长度为㏒2(n+1)-1,但是它有一个很大的缺点,是必须要求查找的序列是顺序存储有序表。
每种算法都可以用迭代和递归来表示,以下我将用C/C++来分别表示。
C/C++ 迭代形式:

#include<stdio.h>
int find(int a[],int x,int low,int high)
{
    int mid;
    if(low>high)           //if  ....   else ....  error!!!
    return -1;
 while(low<=high)
 {
     mid=(low+high)/2;
    if(a[mid]==x)
    return mid;
    else if(a[mid]>x)
     high = mid-1;

    else if(a[mid]<x)
     low = mid + 1;
 }
}
int main()
{
int a[20]={2,3,6,7,12,18,19,21,25,28,30,33,37,39,42,45,47,49,50,51};
int x,i;
printf("已有的数是:\n");
for(i=0;i<20;i++)
printf("%d ",a[i]);
printf("\n请输入要查找的数:");
scanf("%d",&x);
if((i=find(a,x,0,19))>=0)
printf("%d是第%d个数\n",x,i+1);
else 
printf("未找到%d\n",x);
 return 0;
}

在if程序处,我为什么要加上一个莫名其妙的注释——if…else …error。因为之前我想用这个结构来实现,但后来发现我犯了一个低级的错误,我们的目的是要在子程序中不停循环变换上下限,进行分而治之的算法,而if …else …只是判断执行一遍,当然与我们的要求不一样。

C/C++ 递归形式:

#include<stdio.h>
int find(int a[],int x,int low,int high)
{int mid;
 if(low>high)
 return -1;
 mid=(low+high)/2;
return mid;
 if(a[mid]>x)
 return find(a,x,low,mid-1);
 return find(a,x,mid+1,high);
}
int main()
{
int a[20]={2,3,6,7,12,18,19,21,25,28,30,33,37,39,42,45,47,49,50,51};
int x,i;
printf("已有的数是:\n");
for(i=0;i<20;i++)
printf("%d ",a[i]);
printf("\n请输入要查找的数:");
scanf("%d",&x);
if((i=find(a,x,0,19))>=0)
printf("%d是第%d个数\n",x,i+1);
else 
printf("未找到%d\n",x);
 return 0;
}

伟大的递归算法,只是我们把发生改变的数据又顺手抛给了程序自己处理,虽然给消耗内存栈的空间,但是算法相对简单。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值