将递归转换为迭代

时间:2015-10-27 00:35:57

标签: c# algorithm recursion iteration tail-recursion

我已经做了一些阅读,并且学会了将递归转换为迭代的最佳方法是使用堆栈。但是,由于如何使用返回值,因此很难实现。任何帮助都会很棒。这是递归函数:

public Complex[] fft(Complex[] x, int L) {
    int ii;
    int kk = 0;
    int N = x.Length;

    Complex[] Y = new Complex[N];

    if (N == 1) {
        Y[0] = x[0];
    } else {

        Complex[] E = new Complex[N / 2];
        Complex[] O = new Complex[N / 2];
        Complex[] even = new Complex[N / 2];
        Complex[] odd = new Complex[N / 2];


        for (ii = 0; ii < N; ii++) {
            if (ii % 2 == 0) {
                even[ii / 2] = x[ii];
            }
            if (ii % 2 == 1) {
                odd[(ii - 1) / 2] = x[ii];
            }
        }

        E = fft(even, L);   // RECURSION HERE
        O = fft(odd, L);    // RECURSION HERE

        // RECURSION RESULTS USED HERE
        for (kk = 0; kk < N; kk++) {
            Y[kk] = E[(kk % (N / 2))] + O[(kk % (N / 2))] * twiddles[kk * (L / N)];
        }
    }

    return Y;
}

以下代码不起作用,但它显示了我到目前为止的尝试

public Complex[] fft2(Complex[] x, int L) {
    Stack<Complex[]> stack = new Stack<Complex[]>();
    stack.Push(x);

    int ii;
    int kk;
    int N;

    while (stack.Count > 0) {
        x = stack.Pop();
        kk = 0;
        N = x.Length;

        Complex[] Y = new Complex[N];

        if (N == 1) {
            Y[0] = x[0];
        } else {

            Complex[] E = new Complex[N / 2];
            Complex[] O = new Complex[N / 2];
            Complex[] even = new Complex[N / 2];
            Complex[] odd = new Complex[N / 2];

            for (ii = 0; ii < N; ii++) {
                if (ii % 2 == 0) {
                    even[ii / 2] = x[ii];
                }
                if (ii % 2 == 1) {
                    odd[(ii - 1) / 2] = x[ii];
                }
            }

            stack.Push(even);
            stack.Push(odd);

            // E = fft2(even, L);
            // O = fft2(odd, L);

            for (kk = 0; kk < N; kk++) {
                Y[kk] = E[(kk % (N / 2))] + O[(kk % (N / 2))] * twiddles[kk * (L / N)];
            }
        }
    }

    return Y;
}

1 个答案:

答案 0 :(得分:0)

当您查看代码时,基本上会获得递归,并且停止,如下所示:

N的数组     =&GT;通过递归,计算2个N / 2数组,然后将它们组合

当N == 1时,它就完成了。

然后,你计算每2. N / 2,4。N / 4,... 2 ^ n。 N / 2 ^ n,其中n = log2(N)

数据似乎无法重复使用,因此您必须计算2 ^ n个数组。

如果您的大小是2的功率,例如64,则必须计算64个数组,然后是32,16,8,4,2,1,然后是127个运算(= 2 ^(n + 1) - 1)。

所以问题就变成了:如何将二叉树中的递归操作转换为迭代。

我从SO中选择了其他相同的一般问题:您可以在那里找到算法和代码:

Post order traversal of binary tree without recursion

Convert recursive binary tree traversal to iterative

从递归转换到迭代的更一般问题取决于递归算法,以及数据是否可重用。

希望它有所帮助!