为啥我们需要在这个递归函数中返回

Posted

技术标签:

【中文标题】为啥我们需要在这个递归函数中返回【英文标题】:Why do we need to return in this recursive function为什么我们需要在这个递归函数中返回 【发布时间】:2022-01-17 17:41:24 【问题描述】:

我正在尝试学习递归,所以我决定实现一些使用递归的算法,如二分搜索,但我有一些问题无法理解为什么我们需要在这样的情况下返回:

int binarysearch(int *arr, int x, int left, int right)
    if(right <= left)
        return -1;
    
    int mid = (left + right) / 2;
    if(arr[mid] == x)
        return mid;
    
    if(x < arr[mid])
        return binarysearch(arr, x, left, mid - 1);
    else 
        return binarysearch(arr, x, mid + 1, right);

就像我们没有需要返回的值一样,我们需要的唯一值是在参数中,但是当我删除 return 语句时,我得到了一些未定义的行为。有人可以向我解释为什么我在删除时得到了未定义的返回语句。

编辑:

此返回声明:return binarysearch(arr, x, left, mid - 1); 还有这个:return binarysearch(arr, x, mid + 1, right);

【问题讨论】:

你指的是“return语句”,但是return语句有4个。 函数返回数组中找到值的位置 @PaulHankin 我编辑问题请检查一下 如果你定义一个函数来返回某种数据类型,你必须在每个结束函数执行的分支中使用具有合适值的return 语句。否则你会得到未定义的行为。 @Bodo 但在返回时我指定返回什么值? 【参考方案1】:

这是因为返回值必须通过每个被调用函数的返回值传播到原始调用者。

我会用[i] 来注释每个调用,只是为了区分对同一函数的不同调用。

假设您有数组 1, 2 ,然后您调用 printf("%d", binarysearch[1](array, 2, 0, 1));

然后

mid = 0(因为除以两个整数时会向下取整) 2 &lt; arr[0] ~ 2 &lt; 1 = 00 表示 C 中的 false

因此binarysearch[2](array, 2, 1, 1);binarysearch[1] 内部被调用。在这个新函数中mid = 1arr[1] == 2,所以函数binarysearch[2] 返回1

但是binarysearch[2]binarysearch[1] 内部被调用,所以1 的值现在在binarysearch[1] 内部,为了将值传递给printf,我们必须再次返回它。

如果您删除返回(令我惊讶的是编译器甚至允许您这样做),那么从binarysearch[2] 返回的值将被丢弃并且binarysearch[1] 结束而不会将值返回给printf,但是@ 987654342@ 期望该值存在,因此它只取当时内存中的任何内容,这会导致未定义的行为。

我希望它有点可以理解。

【讨论】:

【参考方案2】:

我从你的问题中了解到,为什么我们需要返回函数中已经存在的语句。

所以首先递归的概念是函数不断地调用自己。

接下来二分查找的概念是通过将列表中的元素一分为二来查找它。

它找出中间并将其与搜索元素进行比较,如果它大于搜索值,则在搜索的其他部分以相同的方式执行搜索。

你提到的return语句是再次调用函数以重复搜索功能。即,在列表的第一部分或第二部分执行搜索。

它重复执行此功能,直到找到要搜索的元素。

简单来说,return 语句将控制权收回到函数的开头。你不能忽略 return,因为函数被声明为 int 并且它必须有一个 return 语句

【讨论】:

如果我们在没有返回语句的情况下调用函数,会再次执行该函数还是什么? 从return语句调用函数的要点是我们必须返回一个值,因为函数的数据类型是int,如果你不想在return语句中调用它,那么按照在前面的示例中,您可以将函数调用存储在变量中并返回它。但是对于除 void 以外的任何数据类型的函数,您都不能跳过 return 语句

以上是关于为啥我们需要在这个递归函数中返回的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的递归函数返回 None?

为啥我的递归函数返回 None?

java中,当实例化子类时会递归调用父类中的构造方法。这个说法对么?为啥

为啥这个递归函数超过调用堆栈大小?

递归幂函数:如果没有初始返回值,为啥会这样?

为啥这个 PHP 递归函数不起作用