在递归计算功率时,我不理解我的方法的输出

时间:2012-10-26 07:34:43

标签: java recursion

当我尝试递归计算2 ^ 8时,我不知道这种方法将如何使用31次。

此方法是否计算O(logN)复杂度的功率?

当我运行它时,输出是:

0
1
2
3
4
5
...
29
30
2^8 is: 256

代码

private static int power(int x, int y)
{
    System.out.println(step++);

    if (y == 0)
        return 1;

    return power(x, y/2) * power(x, y/2);
}

4 个答案:

答案 0 :(得分:6)

在这里,您实际上是使用相同的值对power方法进行两次调用:

return power(x, y/2) * power(x, y/2);

相反,如果你这样写,你可以拨打一半的电话:

int toReturn = power(x, y/2);
return toReturn * toReturn;

如果我们完成您的原始示例,我们将进行31次调用,这就是您所看到的(0到30)。浏览您的代码以了解原因:

power(2, 8)

power(2, 4)
power(2, 4)

power(2, 2)
power(2, 2)
power(2, 2)
power(2, 2)

power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)
power(2, 1)

power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)
power(2, 0)

答案 1 :(得分:2)

正如其他海报所指出的那样,你经常调用power方法。我只是想添加(我不想这样做作为注释),我不建议使用静态变量来计算递归的级别。相反,我建议将当前步骤作为另一个参数传递给函数:

private static int power(int x, int y, int recursiveCallStep)
{
    System.out.println(recursiveCallStep++);

    if (y == 0)
        return 1;

    int toReturn = power(x, y/2, recursiveCallStep);
    return toReturn * toReturn;
}

第一个电话会是:

int result = power(2, 8, 0);

如果你以前做过这件事,你就会意识到同一个步数不止一次输出。

答案 2 :(得分:1)

不,它不是O(logN),它是O(NlogN)

在每次迭代中,您创建的问题只有问题的一半(这很好),但您正在创建其中两个

你应该这样做,而不是

 return power(x, y/2) * power(x, y/2);

 int power = power(x, y/2);
 return power * power;

答案 3 :(得分:0)

完全没有必要使用除草树。这就是为什么你的代码重新计算不止一次相同值的原因。

使用这个更简单的递归代码可以获得更好的复杂性:(你可以看到它是O(N))

private static int power(int x, int y)
{
    System.out.println(step++);

    if (y == 0)
        return 1;
    else
    {
        return x * power(x, y - 1);
    }
}

当X = 2且Y = 3时,堆栈跟踪将为:

power(2,3) = 2 * power(2, 2);
power(2,2) = 2 * power(2, 1);
power(2,1) = 2 * power(2, 0);
power(2,0) = 1;