【发布时间】:2018-09-19 01:08:54
【问题描述】:
理论上应该可以将每个递归方法写成一个迭代方法。
我知道递归函数是尾递归的很容易。例如,可以像这样递归地计算阶乘:
// Recursive:
long fact(long n){
return fact(n, 1);
}
long fact(long n, long r){
return n==1 ?
r
:
fact(n-1, r*n);
}
或者像这样的迭代:
// Iterative:
int fact(int n){
int r = 1;
for(; n>1; n--)
r *= n;
return r;
}
这很简单,因为我们不会将递归方法的结果用于其他事情,而且我们只有一个递归调用,我们将 n 减少 1 次迭代。
我也知道您应该为大多数递归到迭代转换保留一个堆栈。例如,可以像这样递归地进行快速排序:
// Recursive:
void quicksort(int[] array, int left, int right){
if(left >= right) return;
int index = partition(array, left, right);
quicksort(array, left, index-1);
quicksort(array, index+1, right);
}
或者像这样的迭代:
// Iterative:
void quicksort(int[] array, int left, int right){
int[] stack = new int[1024]; // Example size, alternative an actual java.util.Stack could be used
int i=0;
stack[i++] = left;
stack[i++] = right;
while(i>0){
right = stack[--i];
left = stack[--i];
if(left >= right) continue;
int index = partition(array, left, right);
stack[i++] = left;
stack[i++] = index-1;
stack[i++] = index+1;
stack[i++] = right;
}
}
但我现在也想将以下递归方法转换为它的迭代形式:
// Recursive:
int f(int n){
return n<1 ?
0
:
n%2+1 + 3*f(n/2);
}
在这种情况下,它使用递归结果,并将该结果乘以 3。我也不完全确定如何进行迭代。我尝试过这样的事情:
// Iterative:
int f(int n){
int[] stack = new int[1024]; // Example size, alternative an actual java.util.Stack could be used
int i=0;
stack[i++] = n;
while(i > 0){
n = stack[--i];
if(n < 1)
stack[i++] = 0;
stack[i++] = n%2+1 + 3*stack[--i];
}
return stack[0];
}
这显然是行不通的,因为在i=1进入while之前,它在n = stack[--i]处变为0,然后在stack[i++] = n%2+1 + ...处再次变为1,然后在3*stack[--i]处再次变为0,所以它在第一次迭代后停止,并简单地返回stack[0]。当我将递归调用的结果与其他计算(在这种情况下乘以 3)一起使用时,我应该如何将上述递归方法转换为迭代方法?
至于原因:我想将上面的这种递归方法移植到没有任何功能的基于堆栈的语言中,因此我需要迭代方法(带堆栈)。
【问题讨论】:
标签: java loops recursion stack iteration