递归在此代码中的工作原理

how recursion works in this code

本文关键字:工作 代码 递归      更新时间:2023-10-16

我试图了解递归的工作原理。有简单的例子,如阶乘等,我清楚地理解它们,但我无法理解这里如何递归分配 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);
}

你应该自己构建递归树,通过手动来真正理解问题,例如你有一个数组 [2, 4, 6, 0, 1]: Len = 5,左 = 0,右 = 4,那么你称平均值,因为左 =!右,数组一分为二,然后函数调用自身两次,一次是左 = 0,右 = 左+右/2 = 2,另一半调用左 = 3,右 = 4。 这两个调用都不满足条件 right=left,因此对于每个函数(左 = 0,右 = 1)、(左 = 2,右 = 2)和另一个函数(左 = 3,右 = 3)(左 = 4,右 = 4)。除了情况(左 = 0 和右 = 1)之外,每个都从左 = 右开始计算,然后计算的返回:num[左 = 右]/len 和左 = 0 和右 = 1 的情况被拆分并返回大小写(左 = 0,右 = 0)和(左 = 1,右 = 1)。然后返回每个案例,并对每一半求和,剩下的是每个值的总和除以长度。

因此,总结一下,以下是该函数采取的步骤:

平均([2,4,6,0,1]

) => 回报 (平均([2,4,6]) + 平均([0,1])) => 回报 (平均([2,4])+平均([6]))+(平均([0])+平均([1])))=>((平均([2])+平均([4]))+(6/5)))+((0/5)+(1/5)))=>(((2/5)+(4/5)))+ (6/5))+(1/5)=>(6/5+6/5)+1/5=>13/5,瞧。即使对于函数式编程,这也是一种非常奇怪的方法,更常见的方法是:(在伪代码中)

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)
}