算法(三)-分治和递归
递归
直接或间接地调用自身的算法称为递归算法。
阶乘函数:n!={1 n=0 ; n(n-1)! n>0}
int factorial(int n){
if(n==0)
return 1;
return n*factorial(n-1)
}
Fibonacci 数列:F(n)={1 n=0 ; 1 n=1 ; F(n-1)+F(n-2) n>1}
int fibonacci(int n){
if(n<=1)
return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
F
(
n
)
=
1
5
[
(
1
+
5
2
)
n
+
1
−
(
1
−
5
2
)
n
+
1
]
F\left( n \right) =\frac{1}{\sqrt{5}}\left[ \left( \frac{1+\sqrt{5}}{2} \right) ^{n+1}-\left( \frac{1-\sqrt{5}}{2} \right) ^{n+1} \right]
F(n)=51⎣⎡(21+5)n+1−(21−5)n+1⎦⎤
Ackerman函数-双递归函数
排列问题
整数划分问题
Hanoi塔问题
void hanoi(int n,int a,int b,int c){
if(n>0){
/*其中,hanoi(n,a,b,c)表示将塔座a上自下而上,
由大到小叠放在一起的n个圆盘依移动规则移至塔座b上并仍按同样顺序叠放。
move(a,b)表示将塔座a上编号为n的圆盘移至b上*/
hanoi(n-1,a,c,b);
move(a,b);
hanoi(n-1,c,b,a);
}
}
通常,在一个算法中调用另一算法时,系统需在运行被调用算法之前先完成三件事:
1.将所有实参指针、返回地址等信息传递给被调用算法;
2.为被调用算法的局部变量分配存储区;
3.将控制转移到被调用算法的入口。
在从被调用算法返回调用算法时,系统相应地要完成三件事:
1.保存被调用算法的计算结果;
2.释放分配给被调用的数据区;
3.依照被调用算法保存的返回地址将控制转移到调用算法。
一、导引-归并排序
问题导入和例子
伪代码
分治的基本策略
分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解这些子问题,然后将各子问题的解合并得到原问题的解。
分治法所能解决的问题一般具有以下几个特征:
1.该问题的规模缩小到一定的程度就可以容易地解决;
2.该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;
3.利用该问题分解出的子问题的解可以合并为该问题的解;
4.该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
算法分析
算法实现
左递归 右非递归
P1 理解算法,对前面的例子给出算法执行过程
P2 分析算法,给出T(n)公式,并推到计算得出O(T(n))
排序算法比较
讨论思考
类似问题的算法
二、二分搜索
顺序查找O(n)
template<class Type>
int BinarySearch(Type a[],const Type& x,int n){
//找到x时返回其在数组中的位置,否则返回-1
int left=0;
int right=n-1;
while(left<=right){
int middle = (left+right)/2;
if(x==a[middle])
return middle;
if(x>a[middle])
left=middle+1;
else
right=middle-1;
}
return -1;
}
//时间复杂度O(logn)
三、大整数乘法
引入
大整数也称为高精度整数,准确来说,就是指普通程序设计语言中的整数类型值集范围以上的整数 - 比如16位大整数X=1552336656578988 。
计算机程序中,对于一些大整数可以用浮点数来表示它,但只能近似的表示该整数的大小。当大整数相加、相乘时,计算结果中的有效数字也受到了限制。
大整数的准确性在程序执行时如何保证?
分治算法
分治算法改进
小结
四、Strassen矩阵乘法
传统的矩阵乘法
strassen矩阵乘法
时间复杂度
最后结果
改进
五、线性时间选择问题
引入
选择问题
线性时间选择问题
小结
六、棋盘覆盖
问题描述
分治策略
时间复杂度分析
小结
七、快速排序
1.分解
2.递归求解
3.合并
T(n)=O(n2)
T(n)=O(nlogn)
八、最接近点对问题
推荐:最接近点对问题
九、循环赛日程表
推荐:循环赛日程表
十、最大子段和
课后题
第n个斐波那契数列,可以用分治策求解吗?如果认为可以,请简要说明操作方法。
可以,主要是将问题转换为矩阵乘幂的问题,用矩阵(Fn Fn-1)=(Fn-1 Fn-2)*A求A,再用递推式。计算A的n-1次方,与矩阵(F1 F0)相乘可得到Fn的值。