算法第二章上机实践报告
一、实践题目
这一次我要做的是改写二分搜索算法这道题的实践报告,第一次写,没有经验,做的不好还请各位大佬指正。
二、问题描述
话不多说,直接上题。
题目要求是对二分搜索算法进行改写,而且对输入数据也做了限制——已排好序的数组,这就大大减少了我们的作业量。
以下是我个人对题目内容的解读:
输入一个数x,将x插入到已有的数组中,仍为非降序列,判断x在应该插入的位置(可以将数组理解为从下标为-1开始到下标为n结束)。分两种情况进行判断:①如果x不与数组中的元素相等,则输出x该插入位置的左右两个元素的下标,如上面题目输入样例,5应该插入4和6之间,下标分别为[1]和[2]。②如果x与数组等中的元素相等,则输出与x相等的元素的下标,要记得输出两遍,还是以上面的样例为例,将5换成6,则应输出[2]和[2],因为元素6的下标为2。
三、算法描述
这是我自己打的代码:
1 #include<iostream> 2 using namespace std; 3 4 int main() 5 { 6 int a[1000]; 7 int n, x; 8 cin >> n; 9 cin >> x; 10 for (int i = 0;i < n;i++) 11 cin >> a[i]; 12 int left = 0, right = n - 1;//声明两个变量保留数组的上、下限 13 int i = -1, j = n; 14 //上面说过可以将数组理解为从下标为[-1]开始到下标为[n]结束,x必定在这个范围之内 15 //i为x插入位置左边的元素的下标,j为右边的元素的下标 16 int mid; 17 while (left <= right)//当left > right说明遍历完毕,结束循环得出x应该插入的位置 18 { 19 mid = (left + right) / 2; 20 if (a[mid] == x) 21 { 22 i = j = mid; 23 break;//如果在数组中找到与x想等的元素则直接跳出循环 24 } 25 if (x < a[mid]) 26 { 27 j = mid; 28 right = mid - 1; 29 } 30 if (x > a[mid]) 31 { 32 i = mid; 33 left = mid + 1; 34 } 35 }//通过循环,不断的缩小i、j的范围,最终求出x应该插入的位置 36 cout << i << ' ' << j; 37 return 0; 38 }
可能有点繁琐,但我暂时想不出该怎么简化它。我的思路大体上就是不断缩小x所在的区间,最后输出结果就ok了。
四、算法时间及空间复杂度分析
算法的时间复杂度为O(log N),空间复杂度为O(1)。
时间主要花费在循环中,这个过程的依据就是二分查找算法,详情可以戳https://blog.csdn.net/zssapple/article/details/82687478了解。
同样的,算法并不需要申请多余的空间,需要的只是循环开始前定义的几个变量而已。
五、心得体会
要说本次实验的收获的话,估计就是结伴编程中带来的收获吧。之前一直是自己一个人打题,然后打完就直接交上去了,因为老师的话我只需要加一些注释就能看懂,所以一直以来都没怎么注意可读性的问题,老师也没怎么提,直到本次结队编程才有老师提出:自己打的代码要让结对编程的搭档来解释,我才开始注意这个问题。
这次也确实吃了点小亏,可能是因为我的代码不够简介,也可能是我表达的不够清楚,我的搭档对我的代码不是很理解,以至于老师提问的时候,他无法回答。最后花了挺长时间在给他解释我的思路上面,好歹是过了老师这一关。
这次实践,能够让我在以后的编程中更加注意代码可读性的问题,能够让我少走挺多弯路的。