算法de上机实验报告

实验题目:

设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的值

问题描述:

改写二分搜索算法,查找x在数组中的位置,或者介于何处(x不存在数组中)。

算法描述:

排除其他特殊条件下,把数组分为两段,查找数组a[i]<x<a[j],循环查到为止;

算法时间和空间复杂度分析

 

第一次有 n 个元素,第二次n/2个元素,以此类推第k次则为n/2^k个元素。
而时间复杂度一般都是取最坏结果的,并且是以k来作为衡量时间复杂度,
最坏结果,最后一次再剩一个元素,即n/2^k=1,得k=log2n,所以时间复杂
度为 O(logn)。

 

         递归的深度*每次递归所需的辅助空间的个数
         所以空间复杂度是:O(N) 

 

#include<iostream>

using namespace std;
int search(int a[], int x, int n){
    int left=0; int right=n-1;
    int TF=0;
    int i, j;
    while(left<=right){
        int middle=(left+right)/2;
        if(x==a[middle])
        {
           cout<<middle<<" "<<middle<<endl;
           TF=1;
           break;
        }
        if(x==a[0]){
            cout<<"0 0"<<endl;
            TF=1;
            break;
        }
        if(x==a[n-1])
        {
            cout<<n-1<<" "<<n-1<<endl;
            TF=1;
            break;
        }
        if(x>a[middle]&&x<a[n-1]){
        
           if(x<a[middle+1]){
             cout<<middle<<" "<<middle+1;
             TF=1;
             break;}
           }
           left=middle+1;
        if(x<a[middle]&&x>a[0]){
           if(x>a[middle-1]){
             cout<<middle-1<<" "<<middle;
             TF=1;
             break;
                }
           right=middle-1;}
    }
    if(TF==0&&x<a[0]) cout<<"-1 0"<<endl;
    if(TF==0&&x>a[n-1]) cout<<n-1<<" "<<n<<endl;
}
int main(){
    int n, i, x;
    int a[1000];
    cin>>n>>x;
    for(i=0;i<n;i++)
       cin>>a[i];
    search(a,x,n);
    return 0;
}
心得体会:
二分搜索算法改写可行性大,但是要考虑最大最小的情况,每次重置数组的left和right要注意是middle-1还是+1。

posted on 2019-09-22 15:00  小饼干儿  阅读(233)  评论(0编辑  收藏  举报

导航