算法第2章实践报告
算法第2章实践报告
实践报告
实践题目名称
7-2 二分法求函数的零点
问题描述
算法描述
利用二分法求函数零点的思想,当函数在区间内两端点分别大于0,小于0,则可以求两端点的中点对应的函数值与0比较,大于0则重新划分区间为中点到小于0的端点,小于0则划分区间为大于0的端点到中点,不断重复这个过程,逼近零点,直到得到零点。
本题中,题目说明了f(1.5)>0,f(2.4)<0,则以1.5和2.4为左右端点left和right,编写递归算法,先求中点值 mid = (left + right) / 2,再代入函数,若函数值大于0,则零点在mid的左边,要把mid设为左端点,在[mid,right]继续递归,小于0同理,把mid设为右端点,在[left,mid]继续递归,直到找出零点。
需要注意的是,由于计算机浮点数计算精度有误差,当绝对值小于1e-7时,认为值等于0,所以当 fabs(f(mid)) < 1e-7 时,即可结束递归。
代码
#include <bits/stdc++.h>
using namespace std;
double f(double x) {
return pow(x, 5) - 15*pow(x, 4) + 85*pow(x, 3) - 225*pow(x, 2) + 274*x - 121;
}
double solve(double left, double right){
double mid = (left + right) / 2;
if(fabs(f(mid)) < 1e-7)
return mid;
if(f(mid) > 0)
return solve(mid, right);
else
return solve(left, mid);
}
int main(){
double root;
root = solve(1.5, 2.4);
cout << fixed << setprecision(6) << root;
return 0;
}
算法时间及空间复杂度分析
-
时间复杂度
子问题规模为 n/2
划分子问题操作为与0比较和取中值,时间复杂度为O(1)
所以T(n) = T(n/2) + O(1)
由主定理得时间复杂度为O(logN)
-
空间复杂度
由于没有用辅助空间,所以空间复杂度为O(1)
心得体会
- 要注意浮点数精度的问题,在进行浮点数值比较和判断时,接近一个极小的数(如本题的1e-7)即可认为数值有效
- 要注意一些利用二分算法解题的描述,如和中点有关,划分范围有关等问题,可以考虑用二分法求解
分治法的个人体会和思考
-
在遇到一些复杂的算法问题时,分治思想十分重要,将复杂庞大的问题拆分成一个个简单独立的子问题,解决简单的小问题,再一步步向上,把子问题合并,最终把复杂的问题解决。分治法不仅能有效地帮助我们解决问题,还能提高效率。不仅在面对算法问题上,生活中的问题我们也能利用分治思想逐步解决。
-
分治法要注意子问题的拆分方式,因题而异,不能每个问题都是取中值两边或者按照代码模板拼凑。