为什么我的函数在完成(递归)后不会再次调用自身?

时间:2014-10-20 02:23:22

标签: c

我目前完成了我的代码。但由于某种原因,我最后的递归调用没有被触发?我偶然会遗漏某种特殊代码吗?

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

}

3 个答案:

答案 0 :(得分:3)

只有第一次拨打max - 位于main的人 - 实际上会将其返回值分配给任何内容。递归调用返回的值立即丢失;他们所做的工作对最终结果毫无意义。您需要将递归调用的结果分配给maxgreatest

请记住,每次递归调用都会打开一个新的范围,每个范围都有自己的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 greatestint 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$