最近看《算法导论》公开课视频,虽然本科没有学过此类课程,但也能感觉得出来教学水平高于母校,在此就吐槽这一句,进入正题。
第一二课讲到一种分析递归算法的时间复杂度的方法——递归树。长期处于学习技术阶段没有科研导致数学水平直线下降,为了看懂课程不得不捡回一点数学的基础知识。递归算法时间复杂度的计算可以类比于高中时期数列的通项公式计算,虽然曾经基本看到什么类型的题目就知道套用什么公式,现在全忘了,说多了都是泪。但是递归算法时间复杂度的计算又有别于数列通项公式的计算,高中套用的那些公式不符合这种情况。下面介绍具体方法。
对于一个递归算法,首先我们可以分析得出其中一个递归方程:
我们直接考虑一般情况,当h(n)的时间复杂度为时,假设h(n)=,下面对公式进行递归树的展开。
计算时间复杂度就是将构建的递归树的所有节点的值进行求和,S(n) = h(n)+a*h(n)+a2*h(n/b2)+…+ai-1*h(n/bi-1i),设i-1行为倒数第二行,最后一行的值都为常数即T(1)对于时间复杂度的计算无影响,在求和时直接省略,则可得n/bi = 1,i = logbn。
将h(n) = 代入S(n) = h(n)+a*h(n)+a2*h(n/b2)+…+ai-1*h(n/bi-1i)中可得S(n) = *[1+a/ bk+(a/ bk)2+…+(a/ bk)i-1],为等比数列求和。
1.当k=0时,即h(n)为常数,
a = 1时,S(n) = i*1 = logbn = O(logn),
当a !=1时,S(n) = = = O()
2.当k!=0时,
当公比为1时,即a/ bk = 1,S(n) = *(i*1) =*logbn = O(h(n)*logn)
当公比不为1时,S(n) = = ,
当公比大于1时,即a/ bk>1,>k,则S(n) = O()
当公比小于1时,即a/ bk<1,<k,则S(n) = O(h(n))
上面讲完了理论,就得使用实际的例子来运用一下,就拿排序算法中运用递归思想的归并排序来讲,归并排序的思路是将无序数列平均分直到每份的个数为1,将分割的部分两两合并,每次合并都得到一个有序数列,直到最后合并完成。根据算法的表述,可得到归并排序的递归方程为T(n) = 2*T(n/2) + f(n),其中f(n)为每次合并的复杂度,由于每次合并依次将两个有序序列中最小的放入结果序列中,因此复杂度为O(n),因此递归方程表示为T(n) = 2*T(n/2) + n,直接利用通用公式求解得到该方程的复杂度为f(n)*logn即n*logn。