实践题目:
二分查找
输入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
- 问题描述:此题相比二分查找多了一个查找不到时要求输出-1,以及总的比较次数
- 算法描述:用变量count来存放比较次数并将其自加语句放置在循环体头,就不用每次都在if语句后面写了
int count = 0; while(l <= r){ count ++; .... }
比较要查找的数x时,二分查找
int m =(l + r) / 2; if(x == a[m]) { cout << m <<endl << count; return m; } if(x > a[m]){ l = m+1; } else { r = m-1; }
当要查找的数不存在时,即不符合循环体,跳出循环体,输出-1,同时输出比较次数
cout << "-1" <<endl << count; return -1;
具体算法如下,以下给出的是递归的算法,与以上如出一辙,只不过递归算法中,把是否找到放在了循环体外,用来直接为输出服务,不干扰递归调用
int BS(int a[],int x, int l, int r, int &count){ count ++; if( l == r){ if(x == a[l]) return l; else return -1; } while (l < r){ int m = (l + r) / 2; if(x == a[m]) { return m; } if(x < a[m]){ return BS(a, x, l, m-1, count); } if(x > a[m]){ return BS(a, x, m+1
- 算法时间及空间复杂度分析:查找x是否在非降序序列中,在此用的是二分搜索方法。每次都将x与序列中间的值进行比较,相等表示找到;不等继续在其左边/右边查找,如此折半直到找不到为止,每次都是一半一半,故最后时间复杂度为O(logN);而由于在查找过程中没有使用其他辅助空间,为原地操作,故空间复杂度为O(1)。
- 心得体会:在递归算法实现主函数时,出现了一点小插曲,如下:
int main(){ int a[1005]; int n, x, count = 0; cin >> n; for(int i = 0; i < n; i++){ cin >> a[i]; } cin >> x; cout << BS(a, x, 0, n-1, count) << count << endl ; return 0; }
这样的结果是每次输出的结果都是count的初始化值,而解决办法如下:
cout << BS(a, x, 0, n-1, count) << endl ; cout<< count;
分开写输出语句,因为在调用BS算法时,直接连续输出两个结果,会导致BS算法中后续的结果在位置上失守,使得count值传递不到位......