我正在尝试用一种分而治之的算法来查找数组中的最小元素,但递归代码对我来说有点让人头疼。
例如,采用以下伪代码:
procedure R_MIN (A, n)
begin
if (n = 1) then
min := A[0];
else
lmin := R_MIN (A, n/2);
rmin := R_MIN (&(A[n/2]), n - n/2);
if (lmin < rmin) then
min := lmin;
else
min := rmin;
endelse;
endelse;
return min;
end R_MIN
我理解它的方式是我们将数组分成两半,除非我们有基本情况。然后我们找出哪一半有min并重复调用,进一步拆分它(现在我们有4个数组)。但是实际找到min的位置和方式以及C中的代码是什么样的?在我看来,这只有在我们分成两对时才有效。
答案 0 :(得分:1)
它从数组的左半部分和右半部分的先前递归调用中找到最小值。当达到基本情况并且阵列的长度为1时,则该长度为1的子阵列的最小值。然后取该最小值并与另一半的最小值进行比较。两者中的较低者是该子阵列的最小值。返回进行比较等等......
如果您将伪代码翻译为C:
#include <stdio.h>
int rec_min(int A [],int len)
{
int min,lmin,rmin;
if(len==1)
return A[0];
else
{
lmin=rec_min(A,len/2);
rmin=rec_min(A+len/2,len-len/2);
if(lmin<rmin)
return lmin;
else
return rmin;
}
}
int main()
{
int test [10]={3,2,7,4,5,8,1,9,6,10};
printf("%d\n",rec_min(test,10));
return 0;
}
答案 1 :(得分:1)
通过一点距离通常可以更好地理解递归。您需要在数组中找到最小值。如果将大阵列分成两半,则最小值将是每半个最小值的最小值。这是关键概念。而这正是代码的作用。很自然地想知道这种“神奇”是如何发生的,并且居住它可能并不那么容易。但是,在大多数情况下并不需要它。在引擎盖下,重复分成两半的原则,而无需任何额外的干预(这是递归的点 - 一次又一次地调用相同的代码)。并且它停在基本情况下 - 当只剩下一个数字时,最小值就是数字本身(它可能被写为在剩下2个数字时停止,就像你指出的那样 - 但这不是必需的并且会强制做作为最后一步的显式比较,增加了代码的复杂性。