算法第二章上机实践报告
Posted wzc440302
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法第二章上机实践报告相关的知识,希望对你有一定的参考价值。
7-1 二分查找
输入n值(1<=n<=1000)、n个非降序排列的整数以及要查找的数x,使用二分查找算法查找x,输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。
1 int BinarySearch(int a[], int x, int n) 2 { 3 int count = 0; 4 int left = 0; 5 int right = n-1; 6 while(left<=right) 7 { 8 int middle = (left+right)/2; 9 if(x==a[middle]) 10 { 11 count++; 12 cout << middle << endl; 13 cout << count; 14 return 0; 15 } 16 if(x>a[middle]) left = middle + 1; 17 else right = middle - 1; 18 count++; 19 } 20 cout << "-1" << endl; 21 cout << count; 22 return 0; 23 }
这个代码是在书中“二分搜索技术”的代码的基础上修改而来的,主要添加了一个新的变量count储存比较次数,将原本搜索到数据后的返回值改为对count加1,并输出middle数据及count数据。同时,将原本最后在未能搜索到数据时返回-1改为输出-1及count数据并结束binary search。
算法时间复杂度及空间复杂度分析:
以最坏情况考虑,将搜索n/2^m次,所以m=logn,及O(logn)。
空间复杂度应为一个常数,所以为O(1).
心得体会:对于这个二分查找的题目,本身并不难,但是在过程中,我们仍犯了一些不该犯的错误,如对于count变量的处理思路不清晰,没有想到在对middle输出(即在数组中查找到数据后)前应加入对count最后一次搜索的count计算,导致一直不能输出正确数据,最后仍旧是老师提醒后,才明白,说明我们对于这个编程思路不够清晰,没有考虑周全。
7-2 改写二分搜索算法
设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
1 int BinarySearch(int a[], int x, int n) 2 { 3 int left = 0; 4 int right = n-1; 5 int i=0, j=0; 6 while(left<=right) 7 { 8 int middle = (left+right)/2; 9 if(x==a[middle]) 10 { 11 cout << middle << " " << middle; 12 return middle; 13 } 14 if(x>a[middle]) left = middle + 1; 15 else right = middle - 1; 16 } 17 if(left>right) 18 { 19 i = left-1; 20 j = left; 21 } 22 cout << i << " " << j; 23 return -1; 24 } 25 26 int main() 27 { 28 int n; 29 int x; 30 cin >> n >> x; 31 int a[n]; 32 for(int i=0; i<n; i++) 33 { 34 cin >> a[i]; 35 } 36 if(x<a[0]) 37 { 38 cout << "-1 0"; 39 return 0; 40 } 41 else if(x>a[n-1]) 42 { 43 cout << n-1 << " " << n; 44 return 0; 45 } 46 BinarySearch(a,x,n); 47 return 0; 48 }
这个代码依旧是在“二分搜索技术”代码的基础上修改而成的。首先,因为数组为已排好序的数组,所以对于x比数组最大值大和比最小值小的情况,题目以明确给出“若x小于全部数值,则输出:-1 0 若x大于全部数值,则输出:n-1的值 n的值”的要求。因此,我们在main函数中加入判断语句,判断x是否在数组中,并对两种情况给出相应输出并直接结束。在判断x位于数组中后,进入binarysearch函数进行搜索。同样,我们在开头加入两个新变量i和j来保存小于x的最大元素的最大下标i和大于x的最小元素的最小下标j。然后,在已查找到x的返回值middle之前,加入对middle的两次输出,以满足题目要求的i和j的输出。另外,在所有判断完成后。可以断定只有当left指向比right大的时候,才会跳出while循环。此时x不在数组中,数组中比x大的数为left所指向的数,比x小的数为right所指向的数,因此,对i赋值left-1(left-1在此时与right所指向相同),j赋值left,并输出i和j。
5.心得体会(对本次实践收获及疑惑进行总结)
这次上机实验我和邓润明同学一起做了3个实践的代码。主要学习到的就是在写完代码后一定要检查。在写“7-3 两个有序序列的中位数”中,我们浪费了大量时间改写各个地方的条件判断,最后在一次重新看代码时,我才发现是i和j打错了造成的。原应该为“if(s1[i] < s2[j])”的判断语句,我们写成了“if(s1[i] < s2[i])”,再加上这个代码在pta中凑巧每次都能过5个中的3个,我们一直没有怀疑是代码写错,一直在为代码添加新的判断语句,或者修改原语句。
以上是关于算法第二章上机实践报告的主要内容,如果未能解决你的问题,请参考以下文章