算法第二章上机实验报告
1.题目:改写二分搜索算法
2.问题描述:找出特定数字x在特定有序序列中的位置,若x不在序列中,则输出序列中小于x的最大元素的位置和大于x的最小元素的位置,若x在序列中,则输出两次x在序列中的位置
3.算法描述:定义一个函数BS(int a[],int x,int n)返回所求位置,a数组用来存放序列,x是特定数字,n是序列长度。在函数中定义left=0,right=n-1,middle为序列位置的中间值。当left<=right时,若x=a[middle],则返回middle;若x<a[middle],则right=middle-1;否则left=middle+1,不断循环直至有返回或left>right。当left>right时,说明此刻的left或right就是所求位置,返回left或right。在主函数中调用函数并按要求如第二段代码输出结果。
int BS(int a[],int x,int n) { int left=0;int right=n-1; while(left<=right){ int middle=(left+right)/2; if(x==a[middle]) return middle; if(x>a[middle]) left=middle+1; else right=middle-1; } return left; }
int k=BS(a,x,n); if(x==a[k]) cout<<k<<" "<<k<<endl; if(x<a[k]) cout<<k-1<<" "<<k<<endl; if(x>a[n-1]) cout<<n-1<<" "<<n<<endl;
4.算法时间及空间复杂度分析:
a.时间复杂度:在BS函数里面,规模是n,每次循环都减少一半的规模即为原来的1/2,故时间复杂度为O(logn)。
b.空间复杂度:申请了一个长度为n的数组,故空间复杂度为O(n)。
5.心得体会:
a.要细心,清楚题目要求。比如题目说当搜索元素在数组中时i和j相等,当时就只输出了一个数i,其实应该要输出i和j,只不过它们相等而已。
b.要考虑周到,清楚每一个情况的输出。比如当left>right时我返回的是left,此刻主函数不用再判断x<a[0]的情况,因为这个情况已经蕴含在x<a[BS(a,x,n)]里。否则就输出两行-1,0