简体   繁体   English

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

[英]Why is my function not calling itself again when it is finished (recursion)?

I currently finished my code. 我目前已完成代码。 but for some reason my recursive call at the end isn't being triggered? 但是由于某种原因,我的递归调用没有被触发? Is there some sort of special code I am missing from this by chance? 我是否偶然地缺少某种特殊代码?

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

}

Only the first call to max - the one located in main - actually assigns its return value to anything. 实际上,只有第一个对max调用(位于main调用)才将其返回值分配给任何对象。 The values returned by the recursive calls are immediately lost; 递归调用返回的值立即丢失; the work they do is meaningless to the end result. 他们所做的工作对最终结果毫无意义。 You need to assign the result of the recursive call to max to greatest . 您需要分配递归调用的结果, maxgreatest

Remember that each recursive call opens up a new scope, each with its own version of the greatest variable. 请记住,每个递归调用都会打开一个新作用域,每个作用域都有其自己的greatest变量版本。 The assignments within each recursive call only modify their version of the variable, not the one from the enclosing scope; 每个递归调用中的分配仅修改变量的版本,而不修改封闭范围中的变量的版本。 this means that the version from the very first call is never set to anything after taking the value of arr[0] ; 这意味着从第一个调用开始的版本在采用arr[0]的值之后就不会设置为任何值; and that's the version whose value is returned to main when the outermost call resumes, regardless of the work done in between by the recursive calls. 这就是当最外层调用恢复时,其值将返回到main的版本,而不考虑递归调用之间进行的工作。

You also have an unrelated error, which is that you recurse into another call to max (and assign to greatest within that call) before checking whether you've reached the end of the array, which will overflow beyond the end of the array and overwrite the final result with whatever is found there (as Paul points out, you also assign to greatest before making the comparison against the current value, so the comparison is essentially meaningless). 你也有一个无关的错误,这是你递归到另一个呼叫到max (并分配给greatest该呼叫内)检查您是否已经达到了数组的结束,这将溢出超出了数组的末尾并覆盖最终的结果与任何被发现存在(如保罗指出,你也分配到greatest庄家防范当前值进行比较之前,因此比较基本无意义的)。 You need to move everything inside the checks to make sure this doesn't occur. 您需要移动支票内的所有内容以确保不会发生这种情况。

I believe the recursive call is being triggered, but isn't doing what you want. 我相信递归调用被触发,但没有执行您想要的操作。 you initialize greatest to arr[start] (in this case 8), and never assign anything else to it, so of course your function is returning 8. Instead, it seems like your function should return arr[start] if start >= end, and otherwise should return either arr[start] or max(arr, start+1, end), whichever is larger. 您将great初始化为arr [start](在本例中为8),并且从不分配其他任何内容,因此,您的函数当然返回8。相反,如果start> = end,您的函数似乎应该返回arr [start]。 ,否则应返回arr [start]或max(arr,start + 1,end)中较大的一个。

Your algorithm is a little messed up. 您的算法有些混乱。 For instance, greatest<arr[start] will never be true, because you just set greatest = arr[start] . 例如, greatest<arr[start]永远不会为真,因为您只设置了greatest = arr[start] Here's a commented working algorithm: 这是一个经过评论的工作算法:

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

with output: 输出:

paul@thoth:~/src/sandbox$ ./max
12
paul@thoth:~/src/sandbox$ 

Let's go through it with a simple list, {1, 5, 3}. 让我们通过一个简单的列表{1,5,3}来进行遍历。 Each indentation level represents one of your recursive function calls. 每个缩进级别代表一个递归函数调用。 Every time we see max() , we go up a level - every time we see return , we go back a level. 每次看到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

Remember, every time you see int greatest , that's a different variable that's being created. 记住,每次看到int greatest ,这都是一个不同的变量正在创建。 They all have the same name, but since they're all in separate scopes, they're still all different. 它们都具有相同的名称,但是由于它们都在不同的作用域中,所以它们仍然是不同的。 The int greatest in call 2, for instance, is completely separate from the int greatest in call 1, just as the int greatest in call 1 is completely separate from the int greatest in main() . int greatest在呼叫2,例如,是从完全分开int greatest呼叫1,正如int greatest呼叫1是从完全分开int greatestmain()

EDIT: From the comments, if you want the index of the maximum value as well, this'll do it: 编辑:从注释中,如果您也想要最大值的索引,则将这样做:

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

output: 输出:

paul@thoth:~/src/sandbox$ ./max
Greatest value is 12 at index 4
paul@thoth:~/src/sandbox$ 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM