算法第二章上机实践报告

7-2 改写二分搜索算法

设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。

输入格式:

输入有两行:

第一行是n值和x值; 第二行是n个不相同的整数组成的非降序序列,每个整数之间以空格分隔。

输出格式:

输出小于x的最大元素的最大下标i和大于x的最小元素的最小下标j。当搜索元素在数组中时,i和j相同。 提示:若x小于全部数值,则输出:-1 0 若x大于全部数值,则输出:n-1的值 n的值

输入样例:

在这里给出一组输入。例如:

6 5
2 4 6 8 10 12

输出样例:

在这里给出相应的输出。例如:

1 2

我的代码:
#include<iostream>
using namespace std;
void find(int a[],int x,int n){
    int l=0;int r=n-1;
    while(l<=r){
        int mid=(l+r)/2;
        if(x==a[mid]) {cout<<mid<<" "<<mid;return;}
        else if(x>a[mid]){l=mid+1;}
        else {r=mid-1;}
    }
    if(x<a[l]) cout<<l-1<<" "<<l;
    if(x>a[l]) cout<<l<<" "<<l+1;
    return;
}
int main(){
   int n,x,p;
   int a[100001];
   cin>>n;cin>>x;
   for(int i=0;i<n;i++)
   cin>>a[i];
     if(x<a[0])
     {
        cout<<-1<<" "<<0;
     }
     else if(x>a[n-1])
     {
        cout<<n-1<<" "<<n;
     }
   else find(a,x,n);
   return 0;
}
 
算法描述:这次是改写二分搜索方法,查找x是否在非降序序列当中,二分搜索方法,每次将x与中间的值比较,若比中间序列大则将缩减一半,搜索右边的序列,在将x与右边序列的中间的值进行比较,一直到查找到相同的值或者找不到为止。我的代码先是将x与最左边和最右边的数进行比较,若小于最左边的数或者最右边的数则直接输出相对应的值,若满足则去中间去寻找,二分搜索的方式去查找,在创建数组的左边小于右边的情况下进行循环查找,取mid = (left + right)/2;将x与mid比较,若x>mid,则left= mid + 1;若x<mid,则right = mid - 1;直到相等或者找不到为止,而题目要求的找到则直接输出,找不到时输出x左右两边下标,直接在二分搜索结束时比较x与最后一个数组中间数比较,在输出两边的数的下标即可。
 
算法时间及空间复杂度:时间复杂度:第一次在n个数中查找,第二次在n/2中查找,第n次在n/2的(x-1)次方。最坏的情况循环x次后找到,x=log2;所以时间复杂度为O(logN);
                                        空间复杂度:在主函数中给变量分配的空间为常数,所以空间复杂度为O(1);
 
体会:这道题一开始在二分搜索的基础上更改,一开始我和同伴选择了一个个条件判断在输出,结果将时间复杂度扩大到了O(n),老师最后说的时候,提点了我们,这样二分搜索的意义就不在了,直接在数组中查找也是O(n)的复杂度,最后我们一起讨论,可以在函数中直接比较,省去了不必要的时间,通过这次的上机学习,两个人一起做一道题会比一个人有更多的思路,还能了解别人打代码的方式和习惯,是一次很有意义的,有收获的一次学习机会,让自己能够学到更多的知识,得到更好的提高。
 
posted @ 2019-09-20 17:12  严德怀  阅读(162)  评论(0编辑  收藏  举报