算法学习---查找(二)-二分查找

来源:互联网 发布:网络危害 编辑:程序博客网 时间:2024/06/07 02:21
二分查找
题目:查找学生信息
时间限制:1秒  内存限制:32M 特殊判题:否
题目描述:
          输入N个学术的信息,然后进行查询
输入:
     输入的第一行为N,即学生的个数(N<=1000)
接下来的N行包括N个学生的信息,信息格式如下:
01 李江 男 21
02 刘唐 男 23
03 张军 男 19
04 王娜 女 19
然后输入一个M(M<=10000),接下来会有M行,代表M次查询,每行输入一个学号,格式如下:
02
05
03
01
04
输出M行,每行包括一个对应于查询的学生的信息。
如果没有对应的学生信息,则输出“No Answer!”;
样本输入:
4
01 李江 男 21
02 刘唐 男 23
03 张军 男 19
04 王娜 女 19
5
02
05
03
01
04
来源:2003年清华大学计算机研究生机试真题

      对于此题要注意的是时间复杂度的问题。如果我们采用每次询问时线性遍历数组来查找是否存在我们需要查找的元素,那么,该算法的瞬间复杂度达到了O(n*m)(查找次数*每次查找所需比较的个数),而这个已经达到千万数量级,是我们所不愿意看到的。于是,我们只有另外找方法来解决该题。
没错就是用二分查找。未来符合查找空间单调有序的要求,我们首先要对所有数组元素按照学号关键字进行升序排列。当数组内各元素已经升序有序时,我们就可以在每次询问某个特定学号的学生是否存在时,使用二分查找来查找该学生。
      利用二分查找,原本O(n*m)的时间复杂度被优化到O(nlogn(排序)+m*logn),这个时间复杂度是符合要求的。
#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;struct Student{//用于表示学生个体的结构体char no[100];//学号char name[100];//姓名int age;//年龄char sex[5];//性别bool operator < (const Student & A) const{//重载小于运算符使其能使用sort函数进行排序return strcmp(no,A.no)<0;}}buf[1000];int main(){int n;printf("test begins\n");while(scanf("%d",&n)!=EOF){   for(int i=0;i<n;i++){scanf("%s%s%s%d",buf[i].no,buf[i].name,buf[i].sex,&buf[i].age);}//输入   int t;   scanf("%d",&t);//有t组询问   while(t--!=0){int ans=-1;char x[30];scanf("%s",x);//待查找学号int top=n-1,base=0;//开始下标为0,结束下标为n-1,查找子集为整个buf数组while(top>=base){//当查找子集不为空集时重复二分查找int mid=(top+base)/2;//计算中间点下标int tmp=strcmp(buf[mid].no,x);if(tmp==0){ans=mid;break;//若相等,则查找完成跳出二分查找}else if(tmp>0) top=mid-1;//若大于,则结束下标变为中间点前一个点下标elsebase=mid+1;}if(ans==-1){//若查找失败printf("No Answer!\n");}elseprintf("%s %s %s %d",buf[ans].no,buf[ans].name,buf[ans].sex,buf[ans].age);//若查找成功   }}return 0;}



0 0
原创粉丝点击