算法第二章上机实践报告

时间:2019-09-22
本文章向大家介绍算法第二章上机实践报告,主要包括算法第二章上机实践报告使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、实践题目

二分查找:输入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 #include<iostream>
 2 using namespace std;
 3 
 4 int BinarySearch(int* a, int n,int x, int &com){
 5     int left = 0;
 6     int right = n-1;
 7     while(left <= right){
 8         int middle = (left + right) / 2;
 9         if(x == a[middle]){
10             com++;
11             return middle;
12         }
13         if(x > a[middle]){
14             com++;
15             left = middle + 1;
16         }
17         else{
18             com++;
19             right = middle-1;
20         }
21     }
22     return -1;
23 } 
24 
25 int main(){
26     int a[1001];
27     int n;
28     cin >> n;
29     for(int i=0; i<n; i++){
30         cin >> a[i];
31     }
32     int x;
33     cin >> x;
34     int com = 0;
35     int location = BinarySearch(a, n, x, com);
36     cout << location<< endl;
37     cout << com;
38     return 0; 
39 }

该题核心算法是二分查找,它的基本思想是:将n个元素分成个数大致相同的两半,取a[n/2]与x作比较。如果x=a[n/2],则找到x,算法终止;如果x<a[n/2], 则只在数组a的左半部继续搜索;如果x>a[n/2], 则只在数组的右半部分继续搜索x。

其实这道题的主要部分与书上第17页的例题基本相同,只是多了一个输出比较次数,所以我们只需在原本的基础上增加一个用于统计次数的变量,并且考虑这个变量该如何返回输出。又因为一个函数只能返回一个值,我们用于返回下标,所以num选择使用引用的方法,直接改变主函数里的实参。

四、算法时间及空间复杂度分析

1、时间复杂度:

我们容易看到,每执行一次算法的while循环,待搜索数组的大小减小一半,循环体内运算需要O(1)时间。因此,在最好的情况下,也就是第一次循环,一次比较就找出了x,整个算法的时间复杂度为O(1);在最坏的情况下,也就是在最后才确定结果,while循环被执行了O(logn)次,整个算法的时间复杂度为O(logn).

2、空间复杂度:

因为整个过程中用到的辅助空间只有一个数组a,所以空间复杂度为O(1)。

五、心得体会(对本次实践收获及疑惑进行总结)

1、我们一开始用的是递归的方法,结果总是出错,连下标的输出都不正确,百思不得其解,然后我和小伙伴打开了书,发现我们将while循环用在了递归里......当时真的觉得自己是zhu。说到底,我们还是对于算法本身的理解不够到位,过于依赖书本,习惯了直接按照书上的代码去敲,却没有进一步的思考。这也给了我一定的警示—我需要有脱离书本独自将代码打出来的能力。

2、之后我们就选择了非递归的方法,为了简洁有效的输出num,我们想到了引用方式的传参,然而num的输出还是会出错,它总是比我们期望的要少1,我们还天真的在最后让它加上1输出。嗯,在dev里运行样例成功了。于是我们期待地将它放进了pta,嗯......失败了。于是我们又翻来覆去的找,发现是我们将num++放在了renturn的后面,导致结果出错。果然是细节决定成败。

3、其实一开始我觉得这道题还挺简单的,不就是在例题的基础上加一个变量来返回比较次数吗?然而现实狠狠地打了我一下,我们搞了很久很久......但是我回过头去看,我们犯的那些错误都是很基础的,反应过来后觉得我自己真的是蠢到哭。也让我更深刻地认识到理想和现实还是有很大差距的,在理解算法核心思想的同时,我更需要有将想法变成可实现的代码的能力,毕竟我们的最终目的还是期望打出可以解决问题的代码。而这种能力不是我光天天看书就可以获得的,我更需要脱离书本实际操作,在不断解决错误中提高自己的能力,就像这次,通过打代码,我对二分算法有了更深入的了解,虽然我以后可能还会犯与这两个类似的错误,但我相信我可以更快的发现并解决。

原文地址:https://www.cnblogs.com/WWYlaowu/p/11567993.html