如何手动可视化递归算法的流程?

时间:2018-01-09 05:10:25

标签: java recursion

我有一个为给定数字生成partitions的算法。我想要一种方法在纸上写下这个程序的流程,以便我能更好地理解它。

我试图在下面的方法中跟踪循环中的递归:

 public static long calculate(final long totalSum, final long restriction) {
        appendLineToFile("Calculate function called with values: ");
        appendLineToFile("INPUT: totalSum: " + totalSum);
        appendLineToFile("INPUT: restriction: " + restriction);


        if (totalSum <= 1) {
            // recursive stopping condition
            appendLineToFile("==========recursive stopping condition==========");
            return 1;
        }
        long sum = 0;
        for (long k = 1; k <= restriction; k++) {
            appendLineToFile("Loop begins with k: " + k + " and restriction value: " + restriction);
            sum = sum + calculate(totalSum - k, k);
            appendLineToFile("For Ends" + " Sum in loop is: " + sum + " calculate(totalSum - k, k): " + (totalSum - k) + "," + k);

        }
       // appendLineToFile("=======Returning sum: " + sum + "===========");
        return sum;
    }

以下是输入6和3的输出:

Calculate function called with values: 
INPUT: totalSum: 6
INPUT: restriction: 3
Loop begins with k: 1 and restriction value: 3
Calculate function called with values: 
INPUT: totalSum: 5
INPUT: restriction: 1
Loop begins with k: 1 and restriction value: 1
Calculate function called with values: 
INPUT: totalSum: 4
INPUT: restriction: 1
Loop begins with k: 1 and restriction value: 1
Calculate function called with values: 
INPUT: totalSum: 3
INPUT: restriction: 1
Loop begins with k: 1 and restriction value: 1
Calculate function called with values: 
INPUT: totalSum: 2
INPUT: restriction: 1
Loop begins with k: 1 and restriction value: 1
Calculate function called with values: 
INPUT: totalSum: 1
INPUT: restriction: 1
==========recursive stopping condition==========
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 1,1
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 2,1
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 3,1
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 4,1
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 5,1
Loop begins with k: 2 and restriction value: 3
Calculate function called with values: 
INPUT: totalSum: 4
INPUT: restriction: 2
Loop begins with k: 1 and restriction value: 2
Calculate function called with values: 
INPUT: totalSum: 3
INPUT: restriction: 1
Loop begins with k: 1 and restriction value: 1
Calculate function called with values: 
INPUT: totalSum: 2
INPUT: restriction: 1
Loop begins with k: 1 and restriction value: 1
Calculate function called with values: 
INPUT: totalSum: 1
INPUT: restriction: 1
==========recursive stopping condition==========
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 1,1
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 2,1
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 3,1
Loop begins with k: 2 and restriction value: 2
Calculate function called with values: 
INPUT: totalSum: 2
INPUT: restriction: 2
Loop begins with k: 1 and restriction value: 2
Calculate function called with values: 
INPUT: totalSum: 1
INPUT: restriction: 1
==========recursive stopping condition==========
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 1,1
Loop begins with k: 2 and restriction value: 2
Calculate function called with values: 
INPUT: totalSum: 0
INPUT: restriction: 2
==========recursive stopping condition==========
For Ends Sum in loop is: 2 calculate(totalSum - k, k): 0,2
For Ends Sum in loop is: 3 calculate(totalSum - k, k): 2,2
For Ends Sum in loop is: 4 calculate(totalSum - k, k): 4,2
Loop begins with k: 3 and restriction value: 3
Calculate function called with values: 
INPUT: totalSum: 3
INPUT: restriction: 3
Loop begins with k: 1 and restriction value: 3
Calculate function called with values: 
INPUT: totalSum: 2
INPUT: restriction: 1
Loop begins with k: 1 and restriction value: 1
Calculate function called with values: 
INPUT: totalSum: 1
INPUT: restriction: 1
==========recursive stopping condition==========
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 1,1
For Ends Sum in loop is: 1 calculate(totalSum - k, k): 2,1
Loop begins with k: 2 and restriction value: 3
Calculate function called with values: 
INPUT: totalSum: 1
INPUT: restriction: 2
==========recursive stopping condition==========
For Ends Sum in loop is: 2 calculate(totalSum - k, k): 1,2
Loop begins with k: 3 and restriction value: 3
Calculate function called with values: 
INPUT: totalSum: 0
INPUT: restriction: 3
==========recursive stopping condition==========
For Ends Sum in loop is: 3 calculate(totalSum - k, k): 0,3
For Ends Sum in loop is: 7 calculate(totalSum - k, k): 3,3
Result is: 7

Process finished with exit code 0

对于三个初始循环,我手写了以下内容:

enter image description here

有关如何手动遍历此内容的任何帮助都将受到高度赞赏

1 个答案:

答案 0 :(得分:1)

如果您逐步完成算法,则可以更轻松地理解算法。

您可以使用缩进来可视化递归调用的深度。

以下是我将这个特定算法可视化的方法:

calculate(6,3)   //function call
sum = 0          //assignment
k = 1
    calculate(5,1)        //indentation shows the call hierarchy
    sum = 0
    k = 1
        calculate(4,1)
        sum = 0
        k = 1
            calculate(3,1)         
            sum = 0
            k = 1
                calculate(2,1)
                sum = 0
                k = 1
                    calculate(1,1)
                    return 1          
                sum = 1            //returning back to the caller
                return 1
            sum = 1
            return 1
        sum = 1
        return 1
    sum = 1
    return 1
sum = 1
k = 2
    calculate(4,2)
    ...

对于较大的输入,输出可能会变得很长,但这种方法可以更容易地查看递归调用。

顺便说一句,你实际上并不需要手工编写所有这些内容。将depth参数添加到您的方法相对容易:

calculate(final long totalSum, final long restriction, int depth) {
     ....
     sum = sum + calculate(totalSum - k, k, depth+1);

然后你可以创建一个方法来输出具有适当缩进的行:

appendIndentedLine(depth, "calculate("+totalSum+....

我将appendIndentedLine的实施作为练习留给您。