1、实践题目:改写二分搜索算法 (20 分)

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

3.算法描述:

使用二分算法寻找目标数x,找到则输出所在的位置,如果未找到,则输出小于x的最大元素的位置i和大于x的最小元素的位置j。i,  j的值其实是二分查找算法里面的right, left。

代码如下:

int BIN(int a[], int key, int n) {
int left = 0;
int right = n - 1;

int i = 0;//小于x的最大元素
int j = 0;//大于x的最小元素
while (left <= right) {
int middle = (left + right) / 2;

if (key == a[middle])
{
i = j = middle;//
cout << i <<" "<<j<<endl;
return middle;
}
if (key > a[middle])left = middle + 1;
else { right = middle - 1; }

}
i = right;
j = left;
cout << i<<" "<< j<<endl;

return -1;
}

4、算法时间及空间复杂度分析:

时间复杂度:函数BIN在a[0]<=a[1]<=...<=a[n-1]共n个升序排列的元素中搜索x,找到x时返回其在数组中的位置,否则返回-1。容易看出,每执行一次while循环,待搜索数组的大小减少一半,因此整个算法在最坏情况下的时间复杂度为O(n)=1*T(N/2)+O(1)=O(logn)。

空间复杂度:各个变量的空间复杂度都是O(1),所以算法空间复杂度为O(1)。

5.心得体会:

通过这次上机实验,我和同伴经过讨论和分析,体验到了一起合作的高效率和不同解题方法的带来的思考,更清楚地认识了二分法的思想。在解题过程中也遇到了一些细节上的错误,比如一起在while循环里多次使用返回的不必要的,因为main函数里已经有return了。通过这次的实验,让我收获很大。