1. 实践题目——二分查找
2. 问题描述
输入n值(1<=n<=1000)、n个非降序排列的整数以及要查找的数x,使用二分查找算法查找x,输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。
输入格式:
输入共三行: 第一行是n值; 第二行是n个整数; 第三行是x值。
输出格式:
输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。
输入样例:
4
1 2 3 4
1
输出样例:
0
2
3. 算法描述
用循环实现的二分搜索算法,具体代码如下:
int BinarySearch(int *a, int x, int n) {
int count = 0;
int left = 0;
int right = n-1;
while(left <= right) {
int middle = (left + right) / 2;
count++;
if (x == a[middle]) {
cout<<middle<<endl<<count;
return 0;
}
else if (x > a[middle]) {
left = middle + 1;
}
else {
right = middle - 1;
}
}
if(left > right) {
cout<<"-1"<<endl<<count<<endl;
}
}
4. 算法时间及空间复杂度分析
1)算法的时间复杂度分析:
二分搜索算法中,每执行一次while循环,待搜索数组的大小减小一半,则
T(n) = T(n/2) + 0(1)
故T(n) = log2(n) + 0(1) = log2(n)
故T(n) = log2(n) + 0(1) = log2(n)
2)算法的空间复杂度分析
由于辅助空间是常数级别的(即没有使用辅助空间),故空间复杂度为0(1)
5. 心得体会
经由本次上机实践,发现以下问题:
1)代码规范有待改进。严格遵守代码规范,可以使程序可读性更高,也更有利于错误的检查。
2)出现循环与递归的嵌套使用问题,在编写代码时应注意将递归与循环分开使用。
3)在查找到的情况下需使用 return 0;语句来终止while循环,否则会任选else if 或 else 代码块继续执行下去,从而导致运行超时。
4)代码最优问题,在编写程序时,我在while循环内的3种比较可能情况中分别使用count++语句,其实只需要在进行比较之前使用一个count++语句就可以实现相同的计数效果。
5)查找不到的情况,由于没有注意count的有效范围,故起初考虑时存在一定问题。后经郑老师提醒发现,if语句的条件其实可以省略,因为是在while循环外部,则代表了除 left <= right 情况外的可能,自然就是 left > right 的情况了。