算法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。