递归,学过,见过,甚至还用过
从来没认真走过一遍
昨天的算法题:求一个数的整数次方,用到了递归,一直卡着不知道怎么走的。
为啥以前没有这个觉悟呢,可能是见过的大部分递归,都是一小段代码的最后一行。执行完递归结果就出来了的那种。昨天这道题呢,递归在中间,并且是一个大循环里的中间,就不知道递归后面的代码是否也需要递归。
刚才过了一遍,这段简单的不行的代码终于被我看明白了。太可怕了。。。眼睛以为我会了,甚至手也以为我会了,但是我的脑子今天才明白一些。(可不敢说 会了!)
代码是这样的:
public static double powerUnsinged(double base, int n) {
System.out.println("n = "+n);
if(n == 0)
return 1;
if(n == 1)
return base;
double res = powerUnsinged(base, n/2);
System.out.print(", res1 = "+res);
res *= res;
System.out.print(", res2 = "+res);
if(n % 2 ==1) {
res *= base;
System.out.println(", res3 = "+res);
}
return res;
}
这些System。out就是我在找递归的过程。
先记录一下我的疑惑
此方法powerUnsinged是计算一个数的正整数次方,base是底数,n是次方数。
我很疑惑,在 double res = powerUnsinged(base, n/2); 这句话进行的递归,这句话后面的代码要不要执行。每一次返回的res到底是啥
看了一张图,瞬间明白所有############回溯阶段+递推阶段
然后我瞬间就明白,关于我写的那些代码,应该怎么运行
解答疑惑:递归句后面的代码是否执行不是一定的,但是循环执行的是整个powerUnsinged方法,如果n为0或1,就直接返回结果了,理论上来说是执行了的,只不过不满足条件或者满足了其他条件(比如n为0或1)导致递归句后面的代码没有实实在在的发挥作用。
用base=2,n=10 来举个例子
double res = powerUnsinged(2, 10/2); 递归,返回值记录在double类型的变量 res中,
这个res_10的值等于powerUnsinged(2, 5)的返回值,也就是res_5的乘方再乘以base。然后res_10的值进行平方,由于10除以2余数为0所以无需再乘base
double res = powerUnsinged(2, 5/2); 递归,返回值记录在double类型的变量 res中,
这个res_5的值等于powerUnsinged(2, 2)的返回值,也就是res_2的乘方。然后res_5的值进行平方,由于5除以2余数为1所以返回值res_5需要再乘base
double res = powerUnsinged(2, 2/2); 递归,返回值记录在double类型的变量 res中,
这个res_2的值等于powerUnsinged(2, 1)的返回值,也就是n=1,返回base,即2
好啦,回溯阶段结束,其中n=1,2,5,10.下面是递推阶段
n=1时,返回2,res_1 = 2
n=2时,得到n=1的返回值2,然后进行平方得到4,无需乘base,返回4
n=5时,得到n=2的返回值4,然后进行平方得到16,需要乘base,返回32
n=10时,得到n=5的返回值32,然后进行平方得到1024,无需乘base,返回1024
最后,得到2的10次方结果为1024
成功!!
详细的步骤,希望我下次蒙蔽的时候再来看能获得一些提示