关于折半查找算法

二月底的末唤来了阳春三月的暖,天清气朗,惠风和煦,有时候真想拿着以前放的风筝,冲出去体验一把田野奔跑的欢乐。但也只是想想而已,越来越宅的我始终也离不开手中的笔记本电脑了。
也不知道是气温上升的缘故还是春困突然上头的缘故,看了几天的折半查找算法才算是把它搞懂。
折半查找算法是一种比顺序查找更高效简洁的算法,其查找长度至多为㏒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;
}

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

    原文作者:查找算法
    原文地址: https://blog.csdn.net/w_honor/article/details/50769102
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞