递归如何在此代码中工作

时间:2018-01-01 07:43:20

标签: c++ recursion

我试图了解递归是如何工作的。有一些简单的例子,比如factorial等,我清楚地理解它们,但我不能理解这里是如何递归分配halfOne和halfTwo的。这里的调用顺序是什么,这段代码中发生了什么?感谢任何帮助。提前谢谢。

    #include <iostream>
    using namespace std;

    const int SIZE = 5;

    double average(int nums[], int left, int right, double len);

    int main()
    {
        int nums[SIZE];
        int left, right;
        double len; //If len was an int, the average would always be zero
        double avg = 0;

        //These are for testing
        long double testNum = 0;
        long double testAvg;

        //Populate the array with random integers from 1 - 100
        for (int i = 0; i < SIZE; i++)
        {
            nums[i] = (rand() % 100) + 1;
            testNum = testNum + nums[i]; //For Testing
        }

        left = 0;
        right = SIZE - 1;
        len = right - left + 1; //For computing the average
        avg = average(nums, left, right, len);

        testAvg = testNum / SIZE; //To test my function
        cout << "Average from assignment: " << testAvg << endl;

        cout << "Average from function: " << avg << endl;

        int x;
        cin >> x;

        return 0;
    }


    //This function will find the average of all the numbers in an array
    //By summing together every number divided by the total len.
    //This works because (1 + 2 + 3)/3 is equal to (1/3) + (2/3) + (3/3)
    double average(int nums[], int left, int right, double len)
    {
        double halfOne, halfTwo;
        //This is the base case which will be evaluated
        if (left == right)
            return (nums[left] / len);

        //The array is split until it is of the size 1
        //And each element is evaluated with the base case
        halfOne = average(nums, left, (left + right) / 2, len);
        halfTwo = average(nums, (left + right + 2) / 2, right, len);

        //Each half is added together to get the final total average. 
        return (halfOne + halfTwo);
    }

1 个答案:

答案 0 :(得分:0)

您应该亲自构建递归树,以便真正理解问题,例如您有一个数组[2,4,6,0,1]: Len = 5,left = 0,right = 4,然后你调用average,因为left =!右边,数组被分成两部分,然后函数调用自己两次,一次使用left = 0和right = left + right / 2 = 2,另一半调用left = 3和right = 4。 这两个调用都没有满足条件right = left所以每个函数再次调用两次(Left = 0,right = 1),(left = 2,right = 2)和另一个(left = 3,right = 3)(左= 4,右= 4)。除了情况(左= 0和右= 1),每个都计算,因为左=右,然后计算的返回:num [left = right] / len和case left = 0和right = 1得到拆分返回大小写(left = 0,right = 0)和(left = 1,right = 1)。然后返回每个案例并将每一个案例相加,剩下的就是每个值除以长度的总和。

总结一下,这里是函数采取的步骤:

平均值([2,4,6,0,1])=&gt;返回(平均值([2,4,6])+平均值([0,1]))=&gt;回报(平均值([2,4])+平均值([6]))+(平均值([0])+平均值([1]))=&gt;((平均值([2])+平均值([4] ]))+(6/5))+((0/5)+(1/5))=&gt;(((2/5)+(4/5))+(6/5))+( 1/5)=&gt;(6/5 + 6/5)+ 1/5 =&gt; 13/5和voilá。

即使对于函数式编程,这是一种非常奇怪的方法,更常见的方法是:(在伪代码中)

double Average(nums[], left, right,len)
{
if left == right
  return num[left]/len
return average(nums,left,left,len)+average(nums,left+1,right,len)
}