用递归树方法求解递归式
[备注:需要修改]
一个递归算法的递归式:T(n)=3T(n/4)+cn2T\left(n\right)=3T\left(n/4\right)+cn^2T(n)=3T(n/4)+cn2
我们先来了解一下这个递归式什么意思:
- 333 表示我们将一个问题分解为333个子问题;
- n/4n/4n/4 则表明每个子问题的规模是原问题的1/41/41/4;
- T()T\left(\right)T() 表明的为递归形式;
- cn2cn^2cn2 表明为合并需要的时间,其中ccc为常数系数c>0c>0c>0。其实也就是算法度Θ(n2)Θ\left(n^2\right)Θ(n2)。
好嘞~,现在来看递归树:

我们可以从上图中得出:
-
该树的长度为:log4nlog_{4}nlog4n。理由为:
原本问题的规模为nnn,到了树的最底层,则为111了,也就是说,每往下一层,则规模为1/41/41/4,我们假设它除去了iii个444(iii个结点),也就是说,n÷41÷42÷..÷4i=1n\div4_{1}\div4_{2}\div..\div4_{i}=1n÷41÷42÷..÷4i=1,换个思维,可以说是:4i=n4^i=n4i=n,换算一下也就是i=log4ni=log_{4}ni=log4n -
每往下一层,其子问题得规模为原问题1/41/41/4,也可以说是根据其结点,也就是结点每往下一层,其规模减少1/41/41/4,我们设置结点为iii,就可以得到第iii层的规模将减少至原规模的14i\dfrac {1}{4^{i}}4i1,又因为nnn为原规模,所以可以得出:
当结点为iii的时候,得出规模为:n4i\dfrac {n}{4^{i}}4in -
每层的节点数都是上层的333倍,所以,当结点为iii时,因此深度为iii的结点数为3i3^i3i
-
我们可以看到递归树的最上面那层,表示一开始的代价为cn2cn^2cn2,我们上面求出了结点为iii的时候,规模为:n4i\dfrac {n}{4^{i}}4in,我现在将其转为代价,结点为iii的时候,代价为 c(n4i)2c\left(\dfrac {n}{4^{i}}\right)^2c(4in)2,我们需要把结点数也算上,结点为iii时,有3i3^i3i个结点,最后乘起来,得到:
3i⋅c(n4i)2=(316)icn23^i\cdot c\left(\dfrac {n}{4^{i}}\right)^2=\left(\dfrac {3}{16}\right)^{i}cn^{2}3i⋅c(4in)2=(163)icn2
现在我们可以用级和去求总代价:
T(n)=∑i=0log4n(316)icn2T\left(n\right)=\sum ^{log_{4}n}_{i=0}\left(\dfrac {3}{16}\right)^{i}cn^{2}T(n)=∑i=0log4n(163)icn2 ①①①
=cn2+(316)cn2+(316)2cn2+...+(316)log4n−1cn2+(316)log4ncn2=cn^{2}+\left(\dfrac {3}{16}\right)^{}cn^{2}+\left(\dfrac {3}{16}\right)^{2}cn^{2}+...+\left(\dfrac {3}{16}\right)^{log_{4}n-1}cn^{2}+\left(\dfrac {3}{16}\right)^{log_{4}n}cn^{2}=cn2+(163)cn2+(163)2cn2+...+(163)log4n−1cn2+(163)log4ncn2
根据公式∑k=0nxk=xn+1−1x−1\sum ^{n}_{k=0}x^{k}=\dfrac {x^{n+1}-1}{x-1}∑k=0nxk=x−1xn+1−1得出:
(316)log4n+1−1316−1⋅cn2\dfrac {\left(\dfrac {3}{16}\right)^{log_{4}n+1}-1}{\dfrac {3}{16}-1}\cdot cn^{2}163−1(163)log4n+1−1⋅cn2
emmmmm,最后的结果好像有点凌乱…
没事~,按照算法导论的思路,我们可以利用一定程度的不精确,将级和∑i=0log4n(316)icn2\sum ^{log_{4}n}_{i=0}\left(\dfrac {3}{16}\right)^{i}cn^{2}∑i=0log4n(163)icn2的log4nlog_{4}nlog4n改为∞∞∞,也就是无穷大。且∑i=0log4n(316)icn2<∑i=0∞(316)icn2\sum ^{log_{4}n}_{i=0}\left(\dfrac {3}{16}\right)^{i}cn^{2}<\sum ^{∞}_{i=0}\left(\dfrac {3}{16}\right)^{i}cn^{2}∑i=0log4n(163)icn2<∑i=0∞(163)icn2
根据公式∑i=0∞xk=11−x\sum ^{∞}_{i=0}x^{k}=\dfrac {1}{1-x}∑i=0∞xk=1−x1得出:
11−(316)⋅cn2=(1613)cn2=Θ(n2)\dfrac {1}{1-\left(\dfrac {3}{16}\right)}\cdot cn^{2}=\left(\dfrac {16}{13}\right)cn^{2}=Θ(n^2)1−(163)1⋅cn2=(1316)cn2=Θ(n2)
①①① 原本在算法导论上的算式应该是这样写的:
T(n)=∑i=0log4n−1(316)icn2+Θ(nlog43)T\left(n\right)=\sum ^{log_{4}n-1}_{i=0}\left(\dfrac {3}{16}\right)^{i}cn^{2}+Θ\left(n^{log_{4}3}\right)T(n)=∑i=0log4n−1(163)icn2+Θ(nlog43)
=cn2+(316)cn2+(316)2cn2+...+(316)log4n−1cn2+Θ(nlog43)=cn^{2}+\left(\dfrac {3}{16}\right)^{}cn^{2}+\left(\dfrac {3}{16}\right)^{2}cn^{2}+...+\left(\dfrac {3}{16}\right)^{log_{4}n-1}cn^{2}+Θ\left(n^{log_{4}3}\right)=cn2+(163)cn2+(163)2cn2+...+(163)log4n−1cn2+Θ(nlog43)
和我自己前面写的的的表达式有些不同,其实就是把我级和的log4nlog4nlog4n减去111,然后把最后一项单独拿出来写,也就是(316)log4ncn2\left(\dfrac {3}{16}\right)^{log_{4}n}cn^{2}(163)log4ncn2,且经过转化为后,为Θ(nlog43)Θ\left(n^{log_{4}3}\right)Θ(nlog43)。也就是说,其实Θ(nlog43)Θ\left(n^{log_{4}3}\right)Θ(nlog43)和(316)log4ncn2\left(\dfrac {3}{16}\right)^{log_{4}n}cn^{2}(163)log4ncn2是一样的。
根据书上所说:
树的最底层深度为log4nlog_{4}nlog4n,有3log4n=nlog433^{log_{4}n}=n^{log_{4}3}3log4n=nlog43个结点,每个结点的代价为T(1)T\left(1\right)T(1),总代价为nlog43T(1)n^{log_{4}3}T\left(1\right)nlog43T(1),即为Θ(nlog43)Θ\left(n^{log_{4}3}\right)Θ(nlog43)。
中间将结点3log4n3^{log_{4}n}3log4n转化为nlog43n^{log_{4}3}nlog43算式如下:
利用其公式alogaN=Na^{log_{a}N}=NalogaN=N得出:
3=nlogn33=n^{log_{n}3}3=nlogn3
利用其公式logbN=logaNlogab=lgNlgblog_{b}N=\dfrac {log_{a}N}{log_{a}b}=\dfrac {lgN}{lgb}logbN=logablogaN=lgblgN得出:
3=nlogn3=nlg3/lgn3=n^{log_{n}3}=n^{lg3/lgn}3=nlogn3=nlg3/lgn
将这个这个算式代入3log4n3^{log_{4}n}3log4n中去:
3log4n=(nlg3/lgn)log4n3^{log_{4}n}=\left(n^{lg3/lgn}\right)^{log_{4}n}3log4n=(nlg3/lgn)log4n
对括号外层的对数也利用其公式logbN=logaNlogab=lgNlgblog_{b}N=\dfrac {log_{a}N}{log_{a}b}=\dfrac {lgN}{lgb}logbN=logablogaN=lgblgN得出:
3log4n=(nlg3/lgn)log4n=(nlg3/lgn)lgn/lg43^{log_{4}n}=\left(n^{lg3/lgn}\right)^{log_{4}n}=\left(n^{lg3/lgn}\right)^{lgn/lg4}3log4n=(nlg3/lgn)log4n=(nlg3/lgn)lgn/lg4
=nlg3/lgn⋅lgn/lg4=n^{lg3/lgn\cdot lgn/lg4}=nlg3/lgn⋅lgn/lg4
=nlg3/lg4=n^{lg3/lg4}=nlg3/lg4
=nlog43=n^{log_{4}3}=nlog43
就算是按照我的那个方式去写,也无所谓,我们也可以直接将(316)log4ncn2\left(\dfrac {3}{16}\right)^{log_{4}n}cn^{2}(163)log4ncn2转换为nlog43n^{log_{4}3}nlog43:
(316)log4ncn2=3log4n⋅116log4n⋅cn2=3log4n⋅14log4n⋅2⋅cn2=3log4n⋅1n2⋅cn2=3log4n=nlog43\left(\dfrac {3}{16}\right)^{log_{4}n}cn^{2}=3^{log_{4}n}\cdot \dfrac {1}{16^{log_{4}n}}\cdot cn^{2}=3^{log_{4}n}\cdot \dfrac {1}{4^{log_{4}n\cdot 2}}\cdot cn^{2}=3^{log_{4}n}\cdot \dfrac {1}{n^{2}}\cdot cn^{2}=3^{log_{4}n}=n^{log_{4}3}(163)log4ncn2=3log4n⋅16log4n1⋅cn2=3log4n⋅4log4n⋅21⋅cn2=3log4n⋅n21⋅cn2=3log4n=nlog43
本文通过递归树方法详细解释了如何求解递归式T(n)=3T(n/4)+cn^2,分析了递归树的结构,推导了算法的时间复杂度为Θ(n^2)。通过将级和的log4n改为无穷大,得出最终的复杂度结果。
1万+

被折叠的 条评论
为什么被折叠?



