1. 递归
递归是一种程序设计技术, 一般可以理解为函数或方法不停的调用自身,最终形成多种嵌套调用的形式。
递归的三要素:
-
递归终止条件 递归需要一个明确的临界点,程序一旦到达了这个临界点,就不用继续往下递归, 防止无限递归。
-
终止处理办法在递归的临界点对应一种简单的情景,这种情景下,应当直接给出问题的解决方案。
-
递归处理方法递归问题必须可以分解为若干个规模较小、与原问题形式相同 的子问题,这些子问题可以用相同的思路来解决,并且合并得到原问题答案。
递归调用过程:
下面以求阶乘说明递归调用过程:


2. 分治法
分治算法的核心思想是将原问题划分为n个规模较小而结构与原问题相似的子问题;递归的解决这些子问题,然后再合并其结果,就得到原问题的解。
分治法分为三个阶段:
- 分解:将原问题分解为一系列子问题,如果子问题的规模任不够小则再继续划分,如此递归下去,直到子问题规模足够小很容易求出解为止。
- 解决:求解规模足够小的子问题。
- 合并:将求出的小规模的问题合并为一个更大规模问题的解,自底向上逐步求出原问题的解。

分治算法框架程序:

设计划分策略,把原问题P划分为k个规模较小的子问题,这是分治法的关键步骤,一般遵循以下原则:
- 平衡子问题原则:分割出的k个子问题规模最好大致相当。
- 独立子问题原则:分割出的k个子问题重叠越少越好,最好k个子问题相互独立,不存在重叠子问题。
3. Master定理
- master定理
分治算法的时间复杂度分析一般需要借助Master定理。
T(n)=aT(n/b)+f(n) T(n) = aT(n / b) + f(n)T(n)=aT(n/b)+f(n)
其中:
-
nnn是问题规模大小;
-
aaa是原问题的子问题个数;
-
n/bn / bn/b是每个子问题的大小,这里假设每个子问题有相同的规模大小;
-
f(n)f(n)f(n)是将原问题分解成子问题和将子问题的解合并成原问题的解的时间。
对上面的式子进行分析,得到三种情况:

Master的三种情况可以简要记忆为:- 若函数nlogba>f(n)n^{log_{b}^{a}}>f(n)nlogba>f(n) ,如情况1,则时间复杂度T(n)=O(nlogba)T(n)=O(n^{log_{b}^{a}})T(n)=O(nlogba)
- 若函数nlogba<f(n)n^{log_{b}^{a}}<f(n)nlogba<f(n) ,如情况3,则时间复杂度T(n)=O(f(n))T(n)=O(f(n))T(n)=O(f(n))
- 若函数nlogba=f(n)n^{log_{b}^{a}}=f(n)nlogba=f(n) ,如情况2,则时间复杂度T(n)=O(nlogbalog(n))T(n)=O(n^{log_{b}^{a}}log(n))T(n)=O(nlogbalog(n))
- Master定理应用
-
二分查找
T(n)=T(n/2)+O(1)T(n) =T(n/2) + O(1)T(n)=T(n/2)+O(1)
分析:a=1,b=2,f(n)=O(1),由此可得:nlogba=0=O(1),所以T(n)=nlogbalog(n)=log(n)a = 1, b = 2, f(n) = O(1), 由此可得:n^{log_{b}^{a}} = 0 = O(1),所以T(n) = n^{log_{b}^{a}}log(n) = log(n)a=1,b=2,f(n)=O(1),由此可得:nlogba=0=O(1),所以T(n)=nlogbalog(n)=log(n) -
归并排序
T(n)=2T(n/2)+O(n)T(n) = 2T(n/2) + O(n)T(n)=2T(n/2)+O(n)
分析:a=2,b=2,f(n)=O(n),由此可得:nlogba=n=O(n),所以T(n)=nlog(n)a = 2, b = 2, f(n) = O(n),由此可得:n^{log_{b}^{a}} = n = O(n), 所以T(n) = nlog(n)a=2,b=2,f(n)=O(n),由此可得:nlogba=n=O(n),所以T(n)=nlog(n) -
二叉树遍历
T(n)=2T(n/2)+O(1)T(n) = 2T(n/2) + O(1)T(n)=2T(n/2)+O(1)
分析:a=2,b=2,f(n)=O(1)由此可得:nlogba=n>O(1),所以T(n)=O(n)a = 2, b = 2, f(n) = O(1)由此可得:n^{log_{b}^{a}} = n > O(1),所以T(n)=O(n)a=2,b=2,f(n)=O(1)由此可得:nlogba=n>O(1),所以T(n)=O(n)
-
509





