算法第二章上机实践报告
实践报告任选一题进行分析。内容包括:
- 实践题目
7-2 改写二分搜索算法 (20 分)
题目来源:《计算机算法设计与分析》,王晓东
设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的值
输入样例:
在这里给出一组输入。例如:
6 5 2 4 6 8 10 12输出样例:
在这里给出相应的输出。例如:
1 2 - 问题描述
简单分析一下这道题的输入和输出:输入是数组的元素个数N,要查找的数字X,以及数组元素的值;而输出是比X要大和要小的两个数组元素的下标,或者输出与X相等的元素的下标。这里的数组是非降序的,所以很容易想到是通过比较得方法来进行查找,因此使用二分查找算法。但是,因为二分查找算法只能查找到与X的值匹配的元素的下标,因此要查找一个不存在的数,需要对算法进行改造。
改造的方法:二分查找算法的边界条件是:Left<=Right,而经过分析,当Left到大于Right时,Left指向了比X要大的那个元素的下标,而Right指向了比X要小的那个元素的下标,(即两者刚好错开了)因此只要在二分查找算法的基础上输出Left和Right即可。 - 算法描述
算法的基本思想:假设数据是按非降序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。
1 int BinSearch(int pta[], int n, int x){ 2 int lens = n; 3 int left = 0; 4 int right = lens - 1; 5 6 while(left <= right){ 7 int mid = (left + right)/2; 8 if(x == pta[mid]) { //成功匹配 9 cout << mid << " " << mid; 10 return 0; 11 } 12 else if(x < pta[mid]){ 13 right = mid - 1; 14 } 15 else if(x > pta[mid]){ 16 left = mid + 1; 17 } 18 } 19 //只有当无法匹配时,才会运行这个部分,这个时候left>right 20 while(left > right){ 21 cout << right << " " << left; 22 return 0; 23 } 24 25 return 0; 26 }
-
算法时间及空间复杂度分析(要有分析过程)
对于n个元素的情况:第一次二分:n/2
第二次二分:n/2^2= n/4
......
m次二分:n/(2^m)
在最坏情况下是在排除到只剩下也没有得到结果,所以为
n/(2^m)=1;
2^m=n;
所以时间复杂度为:log2n
空间复杂度:各个变量的空间复杂度都是O(1),所以算法空间复杂度为O(1)。 -
心得体会(对本次实践收获及疑惑进行总结)
通过这次的二分查找算法,更进一步的体会到了分治法的基本思想在实际问题中的应用,对如何使用二分查找算法以及改写有了进一步的认识。
浙公网安备 33010602011771号