我一直在探索递归,并通过在线查看一些简单的示例开始,这一个返回未排序数组的最大值或最小值。
我理解递归调用堆叠(ha)的想法,然后到达基本情况并向后解开。在这种情况下,在找到两个数字的最小值的方法中调用递归方法,并且我不理解min()方法如何在每个递归方法上以链接结果的方式执行递归方法一起产生正确的结果。
我已经介入了代码,但这让我更加困惑。
这里是递归函数和样本main的java MCVE:
public static int min(int a, int b){
if (a<b)
return a;
return b;
}
public static int minValue(int arr[], int n){
if(n == 0)
return arr[0];
return min(minValue(arr,n-1),arr[n-1]);
}
public static void main(String[] args)
int[] arr = {30,20,21,5,3};
int minVal = minValue(arr,5);
System.out.printf("%d", minVal);
}
我跟踪此代码执行的方式:
first call, in main: minValue(arr,5) n is 5
goes to the recursive method: return min(minValue(arr,4),arr{4}), n is 4
starts to execute min, looks at the first arg
minValue executes again: return min(minValue(arr,3),arr{3}) n is 3
...(does this until n==0 is reached)
then return arr[0] executes and sends "30" back to the int minVal in Main.
显然直接从返回到main这样就忽略了堆栈上等待执行的调用的累积,这没有任何意义。我觉得我错过了min()在minVal()上的工作方式。
TL; DR任何人都可以帮我跟踪minVal()调用中min()的执行情况吗?
答案 0 :(得分:1)
然后返回arr [0]执行并发送&#34; 30&#34;回到Main的int minVal。
这就是错误所在。它没有立即返回main()
。它将其返回到先前的递归调用,其中n
为1
。
然后该调用能够评估min(minValue(arr,0),arr[0])
,因为minValue(arr,0)
调用已返回30
。它调用min(30,30)
并将该值返回到n
为2
的上一个递归调用。
现在minValue(arr,1)
已返回30
,此调用可以评估min(minValue(arr,1),arr[1]) == min(30,20) == 20
并将其返回到n
为3
的上一个递归调用
依旧反向堆栈,直到所有的呼叫都解开。