【问题标题】:Need help understanding this recursive function需要帮助理解这个递归函数
【发布时间】:2020-07-04 04:53:16
【问题描述】:

我正在学习递归,我们应该从数组中获取最大的数字,但我不明白解决方案。

#include<stdio.h>
#include<stdlib.h>
int biggestNumber(int *array, int n);

int main(void){
  int n=3;
  int array[3]={3,4,1};
  fprintf(stdout, "|||||%d\n", biggestNumber(array,n));
  return 0;
}

int biggestNumber(int *array, int n){
  if(n==1){
    return array[0];
  }
  else{
    if(array[n-1]>biggestNumber(array, n-1)){
      return array[n-1];
    }
    else{
      return biggestNumber(array, n-1);  
    }
  }
}

我似乎无法理解这个递归函数。 array[n-1]&gt;biggestNumber(array, n-1)为false后,看不懂返回同一个函数。

【问题讨论】:

  • 不需要进行 2 次递归调用,如果将 biggestNumber(array, n-1) 的结果保存在变量中,然后使用该变量进行比较和返回,则相同的代码可以工作
  • 我会尝试使用尽可能小的数组,这很有意义,所以 2. 并逐行查看代码。这在头脑中非常可行,或者只使用纸和笔。
  • 该函数天真地实现 f(A,n) = { A[1] if n = 1, max(A[N], f(A,n-1)) 否则。

标签: c recursion max function-definition


【解决方案1】:

对于初学者来说,递归函数定义不好,通常会导致未定义的行为。

第一个参数应该用限定符 const 声明,因为数组在函数中没有改变。

第二个参数的类型应该是size_t

如果例如第一个 if 语句的结果为 false,则在函数内递归调用可以被调用两次。

if(array[n-1]>biggestNumber(array, n-1)){
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  return array[n-1];
}
else{
  return biggestNumber(array, n-1);  
         ^^^^^^^^^^^^^^^^^^^^^^^^^
}

函数可以像下面的演示程序所示那样声明和定义

#include <stdio.h>

size_t biggestNumber( const int a[], size_t n )
{

    if ( n < 2 )
    {
        return 0;
    }
    else
    {
        size_t max_i = biggestNumber( a, n - 1 );
        return a[max_i] < a[n-1] ? n - 1 : max_i;
    }
}

int main(void) 
{
    int a[] = { 3, 4, 1 };
    const size_t N = sizeof( a ) / sizeof( *a );

    size_t i = biggestNumber( a, N );

    printf( "The biggest number is %d\n", a[i] );

    return 0;
}

程序输出是

The biggest number is 4

原理很简单。由于该函数是递归的,因此对于任何给定的 n,数组中的元素数)该函数找到数组中具有前 n 个 -1 个元素的最大元素的索引。然后将找到的子数组中的最大值与索引为n-1的元素进行比较。

例如对于第一次递归调用,该函数搜索子数组{ 3, 4 } 中最大元素的索引。

对于这个子数组,函数调用自己来获取由一个元素 { 3 } 组成的子数组。这个值是子数组的最大值,因为太阳数组只包含一个元素。所以为0的元素的索引返回到函数的先前调用。

现在该函数将返回的最大值 3 与索引 (n - 1) 处的元素(即索引 1 处等于 4)的元素进行比较。因此该函数将索引 1 返回到第一次调用功能。

这里再次将最大值 4 与索引 (n - 1) 处的元素的值进行比较,在此调用中等于 2。由于值 1 小于值 4,因此index 1,最大值的索引,返回。

【讨论】:

  • 为什么 size_t 而不是 int?
  • @DuarteArribas 对于初学者,您需要使用 unsigned int 类型。否则 used 可以传递一个负数。 size_t 是用于存储对象大小的类型。它是运算符 sizeof 返回的类型。 int 类型可能太小而无法存储大数组的大小。
  • 为什么不使用 long long unsigned int?
  • @DuarteArribas 因为已经定义了用于此目的的 size_t 类型..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 2023-03-23
  • 2016-11-15
  • 2021-12-26
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多