【问题标题】:Find maximum value in an array by recursion通过递归查找数组中的最大值
【发布时间】:2012-10-18 12:05:19
【问题描述】:
// Find a maximum element in the array.
findMax(A)
   findMaxHelper(A, 0, A.length)

findMaxHelper(A, left, right)
   if (left == right - 1) 
      return A[left]
   else
      max1 = findMaxHelper(A, left, (right + left) / 2)
      max2 = findMaxHelper(A, (right + left) / 2, right)

      if (max1 > max2) 
         return max1 
      else 
         return max2

我很难理解这段伪代码中发生了什么。

有人可以帮助解释每行发生的情况吗?在回答问题之前,我需要理解这段代码。

我知道函数findMax调用了辅助函数findMaxHelper,然后findMaxHelper使用了递归。除此之外,我真的不明白。

【问题讨论】:

  • 嗯,正在发生的一件事是数组的最大元素正在以非常昂贵的方式计算!

标签: arrays algorithm search pseudocode


【解决方案1】:

您正在使用Divide and Conquer 算法从数组中查找最大元素。首先,将数组划分为单个元素(除法),然后比较元素(征服)。您正在使用递归调用 findMaxHelper 来划分数组。

分而治之的大致思路如图:

示例:

这里max 与您的findMaxHelper 函数相同,具有两个参数,即leftright

查看this 示例以更深入地了解该概念。

【讨论】:

  • @JustinBains leftright 是数组(初始数组和中间数组)的第一个和最后一个元素的索引。
  • 对任何难以理解递归代码的人的一般建议:不要试图深入了解并遵循。最好进行“缩小”并尝试了解更大的图景。递归函数通常接受输入,执行基本操作并针对较小的问题重复相同的操作,就像这段代码 sn-p 中一样。您应该尝试找出较小的问题,这是理解此类代码的核心。
【解决方案2】:
#include<stdio.h>
#include<stdlib.h>

int high,*a,i=0,n,h;
int max(int *);

int main()
{

    printf("Size of array: ");
    scanf("%d",&n);

    a=(int *)malloc(n*sizeof(int));         //dynamic allocation
    for(i=0;i<n;i++)
    {
        scanf("%d",(a+i));
    }
        i=0;
    high=*a;
    h=max(a);
    printf("The highest element is %d\n",h);
}

int max(int *a)
{

    if(i<n)
    {   
        if(*(a+i)>high)
        {high=*(a+i);}
    i++;
    max(a);                     //recursive call
    }

    return high;
}

【讨论】:

  • 欢迎来到 SO。请注意,OP 确实要求对伪代码进行解释。包含一个没有解释的代码答案不太可能有用。
【解决方案3】:

递归不建议在数组中找到最大值,因为它不是必需的。 分而治之算法(递归)的时间成本更高。 但即使你想使用它,你也可以使用我下面的算法。基本上,它将数组的最大元素放在第一个位置,并且运行时间几乎是线性的。(虽然这个算法只是一个递归错觉!):

        int getRecursiveMax(int arr[], int size){
          if(size==1){
                      return arr[0];
          }else{
                 if(arr[0]< arr[size-1]){
                                      arr[0]=arr[size-1];
                     }
                 return(getRecursiveMax(arr,size-1));
            }

          } 

【讨论】:

    【解决方案4】:

    Jaguar 很好地阐述了这个概念,Paul 提供了正确而详细的解释。 除此之外,我想分享一个简单的 C 代码,让您了解代码是如何得到的 执行。这是 Jaguar 使用的相同输入的代码:

    #include<stdio.h>
    int findMaxHelper(int A[], int left, int right){
       int max1,max2;
       int static tabcount;
       int loop;
       for(loop = 0 ; loop <tabcount;loop++) printf("\t");
       tabcount++;
       printf(" Entering: findMaxHelper(A, left = %d ,right = %d)\n\n",left,right);
       if (left == right - 1){ 
          for(loop = 0 ; loop <tabcount;loop++) printf("\t");
          printf("\b\b\b\b\b\b\bLeaving: findMaxHelper(A, left = %d ,right = %d)| returning %d\n\n",left,right , A[left]);
          tabcount--;
          return A[left];
       }
       else
       {
          max1 = findMaxHelper(A, left, (right + left) / 2);
          max2 = findMaxHelper(A, (right + left) / 2, right);
    
          if (max1 > max2){ 
        for(loop = 0 ; loop <tabcount;loop++) printf("\t");
        printf("\b\b\b\b\b\b\bLeaving: findMaxHelper(A, left = %d ,right = %d) | returning max1=%d\n\n",left,right,max1);
        tabcount--;
        return max1;
        }
          else {
         for(loop = 0 ; loop <tabcount;loop++) printf("\t");
         printf("\b\b\b\b\b\b\bLeaving: findMaxHelper(A, left = %d ,right = %d)| returning max2=%d\n\n",left,right,max2);
         tabcount--;
         return max2;
        }
    
       }
    }
    
    int main (){
        int A[] = { 34,3,47,91,32,0 };
        int Ans =findMaxHelper(A,0,7);  
        printf( "And The Answer Is = %d \n",Ans);
    }
    

    你可以将代码复制粘贴到你的 linux 机器上...也许在每次 printf 之后放置 sleep(5) 看看递归是如何工作的!... 希望这可以帮助... 我还将在这里分享我系统的输出:

    Entering: findMaxHelper(A, left = 0 ,right = 7)
    
         Entering: findMaxHelper(A, left = 0 ,right = 3)
    
             Entering: findMaxHelper(A, left = 0 ,right = 1)
    
             Leaving: findMaxHelper(A, left = 0 ,right = 1)| returning 34
    
             Entering: findMaxHelper(A, left = 1 ,right = 3)
    
                 Entering: findMaxHelper(A, left = 1 ,right = 2)
    
                 Leaving: findMaxHelper(A, left = 1 ,right = 2)| returning 3
    
                 Entering: findMaxHelper(A, left = 2 ,right = 3)
    
                 Leaving: findMaxHelper(A, left = 2 ,right = 3)| returning 47
    
             Leaving: findMaxHelper(A, left = 1 ,right = 3)| returning max2=47
    
         Leaving: findMaxHelper(A, left = 0 ,right = 3)| returning max2=47
    
         Entering: findMaxHelper(A, left = 3 ,right = 7)
    
             Entering: findMaxHelper(A, left = 3 ,right = 5)
    
                 Entering: findMaxHelper(A, left = 3 ,right = 4)
    
                 Leaving: findMaxHelper(A, left = 3 ,right = 4)| returning 91
    
                 Entering: findMaxHelper(A, left = 4 ,right = 5)
    
                 Leaving: findMaxHelper(A, left = 4 ,right = 5)| returning 32
    
             Leaving: findMaxHelper(A, left = 3 ,right = 5) | returning max1=91
    
             Entering: findMaxHelper(A, left = 5 ,right = 7)
    
                 Entering: findMaxHelper(A, left = 5 ,right = 6)
    
                 Leaving: findMaxHelper(A, left = 5 ,right = 6)| returning 0
    
                 Entering: findMaxHelper(A, left = 6 ,right = 7)
    
                 Leaving: findMaxHelper(A, left = 6 ,right = 7)| returning 0
    
             Leaving: findMaxHelper(A, left = 5 ,right = 7)| returning max2=0
    
         Leaving: findMaxHelper(A, left = 3 ,right = 7) | returning max1=91
    
     Leaving: findMaxHelper(A, left = 0 ,right = 7)| returning max2=91
    
    And The Answer Is = 91 
    

    【讨论】:

      【解决方案5】:

      findMaxHelper每次将数组分成两半,在left,right中求最大值:

      例如你有数组A = [1, 3, 5, 8],调用findMax(A) -> findMaxHelper(A, 0, A.length):

           max1 | max2
           1 3  | 5 8
      
      max1|max2 | max1|max2
      1   |3    | 5   |8
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-04
        • 1970-01-01
        • 2010-12-31
        • 1970-01-01
        • 2016-05-07
        • 2016-06-10
        • 2021-12-08
        相关资源
        最近更新 更多