由于您的示例方法是尾递归,因此将其翻译为迭代样式很容易,甚至不需要显式堆栈。
这里有一些步骤,可应用于任何递归函数:
步骤1:重写方法,因此调用自身一次(你的方法已经这样做了),都只有一个return
语句,使用if
和goto
代替else
,while
,for
和foreach
:
int gcd(int m, int n)
{
int result;
if (n == 0)
{
result = m;
goto done;
}
result = gcd(n, m % n);
done:
return result;
}
步骤2:替换的新参数的参数赋值递归调用和goto
的方法开始:
int gcd(int m, int n)
{
int result;
start:
if (n == 0)
{
result = m;
goto done;
}
int old_m = m;
m = n;
n = old_m % n;
goto start;
done:
return result;
}
如果该方法不是尾递归的方法将需要保存其状态在goto
之前,稍后再恢复它。
步骤3:再次拆下goto
S:
int gcd(int m, int n)
{
int result;
while (true)
{
if (n == 0)
{
result = m;
break;
}
int old_m = m;
m = n;
n = old_m % n;
}
return result;
}
步骤4:使方法看起来更好:
int gcd(int m, int n)
{
while (n != 0)
{
int old_m = m;
m = n;
n = old_m % n;
}
return m;
}
下面是不是尾的示例 - 递归:
int fac(int x)
{
if (x == 0)
{
return 1;
}
return x * fac(x - 1);
}
步骤1:
int fac(int x)
{
int result;
if (x == 0)
{
result = 1;
goto end;
}
result = x * fac(x - 1);
end:
return result;
}
步骤2:
int fac(int x)
{
Stack<int> stack = new Stack<int>();
int result;
start:
if (x == 0)
{
result = 1;
goto end;
}
stack.Push(x);
x = x - 1;
goto start;
end:
if (stack.Count != 0)
{
x = stack.Pop();
result = x * result;
goto end;
}
return result;
}
步骤3:
int fac(int x)
{
Stack<int> stack = new Stack<int>();
int result;
while (true)
{
if (x == 0)
{
result = 1;
break;
}
stack.Push(x);
x = x - 1;
}
while (stack.Count != 0)
{
x = stack.Pop();
result = x * result;
}
return result;
}
第4步:
int fac(int x)
{
Stack<int> stack = new Stack<int>();
while (x != 0)
{
stack.Push(x);
x = x - 1;
}
int result = 1;
while (stack.Count != 0)
{
x = stack.Pop();
result = x * result;
}
return result;
}
来源
2011-09-03 13:51:14
dtb
您的gcd示例中没有收藏,您为什么需要一个堆栈?你想在那里存储什么? –
这完全是一个例子..当然,我知道我甚至不需要在这种情况下使用'堆栈'..但它是最简单的情况下,我可以想到关于递归。 – colinfang