1.思维导图
第二章主要学习了递归与分治策略的相关内容,思维导图如下:
2. 递归
递归算法:直接或间接地调用自身的算法。用函数自身给出定义的函数称为递归函数。在计算机算法设计与分析中,递归技术是十分有用的。使用递归技术往往使函数的定义和算法的描述简捷且易于理解。有些数据结构,如二叉树等,由于其本身固有的递归特性,特别适合用递归的形式来描述。有些问题,虽然其本身并没有明显的递归结构,但用递归技术来求解,可使设计出的算法简捷易懂且易于分析。
构造递归算法的两个要素:边界条件、递归方程(递归函数);递归函数构造是递归算法设计的核心。
递归算法时间复杂度分析主要方法:建立算法基本操作执行次数的递推关系式,之后通过建立递推序列通项的各种数学技巧进行计算。
举例分析阶乘函数时间复杂度:
方法1:阶乘函数可递归定义为
递归函数的时间复杂度分析,常用递推分析法。
factorial(int n)
{
if(n=0)return 1;
else return n*factorial(n-1);
}
T(n)=T(n-1)+1,T(n)=T(n-2)+2,...,T(n)=T(1)+n-1=n,可推出:T(n)=O(n)
方法2:阶乘函数也可以找到相应的非递归方式定义
n!=1*2*3......(n-1)*n
非递归函数的时间复杂度分析,常用主语句频度统计法。
factorial(int n)
{
if(n=0)return 1;
else
{
int p,i;
for(p=1,i=1;i<=n;i++)
{
p=p*i;
}
return p;
}
该函数使用单重循环,T(n)=O(n)
递归算法的表征简洁性可能会掩盖算法运行的低效率。
递归技术是设计分治算法的基础技术。
3. 分治法
分治法将难以直接解决的一个大问题,划分成一些规模较小的子问题,以便于各个击破,分而治之。
分治法所能解决的问题一般具有以下几个特征:
- 该问题的规模缩小到一定的程度就可以容易地解决;
- 该问题可以分解为若千个规模较小的结构自相似问题,即该问题具有最优子结构性质;
- 利用该问题分解出的子问题的解可以合并为该问题的解;
- 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
这条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然也可用分治法,但一般用动态规划较好。
分治法将规模为n的问题分成a个规模为n/b的子问题去解。用T(n)表示该分治法解规模为 的问题所需的计算时间,则有:
通过迭代法求得: