我目前完成了我的代码。但由于某种原因,我最后的递归调用没有被触发?我偶然会遗漏某种特殊代码吗?
int max(int arr[], int start, int end) {
int greatest = arr[start];
if(start < end)
{
if(greatest<arr[start])
{
greatest = arr[start];
}
start++;
max(arr, start, end); // Doesn't seem to be triggering since it only returns 8
}
return greatest;
}
int main()
{
int greatest;
int arr[10] = {8,1,2,3,4,5,6,7,8,9};
int start = 0;
int end = 10;
greatest=max(arr, start, end);
pintf("%d\n", greatest);
}
答案 0 :(得分:3)
只有第一次拨打max
- 位于main
的人 - 实际上会将其返回值分配给任何内容。递归调用返回的值立即丢失;他们所做的工作对最终结果毫无意义。您需要将递归调用的结果分配给max
到greatest
。
请记住,每次递归调用都会打开一个新的范围,每个范围都有自己的greatest
变量版本。每个递归调用中的赋值仅修改它们的变量版本,而不是来自封闭范围的变量;这意味着在获取arr[0]
的值之后,第一次调用的版本永远不会设置为任何内容;并且这是在最外层的调用恢复时其值返回main
的版本,无论递归调用之间的工作如何。
您还有一个无关的错误,即您在检查是否&#39之前递归到max
的另一个电话(并在该电话中分配给greatest
) ; ve到达数组的末尾,它会超出数组的末尾并用最后的结果覆盖最终的结果(正如Paul所指出的那样,在对当前进行比较之前,你还要分配给greatest
价值,所以比较基本上没有意义)。您需要移动支票内的所有内容,以确保不会发生这种情况。
答案 1 :(得分:1)
我认为递归调用是被触发,但是没有做你想要的。你初始化最大的arr [开始](在这种情况下是8),并且从不为它分配任何其他东西,所以当然你的函数返回8.相反,看起来你的函数应该返回arr [start]如果start&gt; =结束,否则应返回arr [start]或max(arr,start + 1,end),以较大者为准。
答案 2 :(得分:1)
你的算法有点搞砸了。例如,greatest<arr[start]
永远不会成立,因为您只需设置greatest = arr[start]
。这是一个评论的工作算法:
#include <stdio.h>
int max(int arr[], int start, int end)
{
if ( start >= end ) {
/* Shouldn't get here, but return 0 if we do */
return 0;
}
else if ( end - start == 1 ) {
/* Only one element, so it's the maximum by definiton */
return arr[start];
}
else {
/* Find the maximum of the rest of the list... */
int greatest = max(arr, start + 1, end);
/* ...and return the greater of it, and the first element */
return arr[start] > greatest ? arr[start] : greatest;
}
}
int main(void)
{
int arr[] = { 8, 1, 2, 3, 12, 5, 6, 7, 8, 9 };
int start = 0;
int end = 10;
int greatest = max(arr, start, end);
printf("%d\n", greatest);
}
带输出:
paul@thoth:~/src/sandbox$ ./max
12
paul@thoth:~/src/sandbox$
让我们通过一个简单的列表{1,5,3}来完成它。每个缩进级别代表一个递归函数调用。每当我们看到max()
时,我们就会上升一级 - 每当我们看到return
时,我们就会返回一个级别。
In main(), int greatest = max(list, 0, 3)
In call 1: (end - start == 1) is false
In call 1: int greatest = max(list, 1, 3)
In call 2: (end - start == 1) is false
In call 2: int greatest = max(list, 2, 3)
In call 3: (end - start == 1) is true
In call 3: return arr[2], which is 3
Back in call 2: greatest now equals 3
Back in call 2: arr[1] == 5, which is > 3, so return arr[1], which is 5
Back in call 1: greatest now equals 5
Back in call 1: arr[0] == 1, which is not > 5, so return greatest, which is 5
Back in main(), greatest now equals 5
请记住,每次看到int greatest
时,都会创建一个不同的变量。它们都有相同的名称,但由于它们都在不同的范围内,它们仍然完全不同。例如,调用2中的int greatest
与调用1中的int greatest
完全分开,就像调用1中的int greatest
与int greatest
中的main()
完全分开一样{1}}。
编辑:从评论中,如果你想要最大值的索引,这就行了:
#include <stdio.h>
int max_index(int arr[], int start, int end)
{
if ( start >= end ) {
return 0;
}
else if ( end - start == 1 ) {
return start;
}
else {
int greatest = max_index(arr, start + 1, end);
return arr[start] > arr[greatest] ? start : greatest;
}
}
int max(int arr[], int start, int end)
{
if ( start >= end ) {
/* Shouldn't get here, but return 0 if we do */
return 0;
}
else if ( end - start == 1 ) {
/* Only one element, so it's the maximum by definiton */
return arr[start];
}
else {
/* Find the maximum of the rest of the list... */
int greatest = max(arr, start + 1, end);
/* ...and return the greater of it, and the first element */
return arr[start] > greatest ? arr[start] : greatest;
}
}
int main(void)
{
int arr[] = { 8, 1, 2, 3, 12, 5, 6, 7, 8, 9 };
int start = 0;
int end = 10;
int greatest = max(arr, start, end);
int index = max_index(arr, start, end);
printf("Greatest value is %d at index %d\n", greatest, index);
}
输出:
paul@thoth:~/src/sandbox$ ./max
Greatest value is 12 at index 4
paul@thoth:~/src/sandbox$