递归,尾递归和迭代

时间:2011-09-10 05:46:49

标签: c recursion iteration tail-recursion

这是我的代码。

递归:

#include <stdio.h>

int Recursion(int m,int n)
{
    if(m==0 || n==0)
        return 1;
    else
        return 2*Recursion(m-1,n+1);
}

void main()
{
    int m,n,result;
    m=3;
    n=-2;
    result=Recursion(m, n);
    printf("%d",result);
}

迭代

#include <stdio.h>

int Recursion(int m,int n)
{
    int returnvalue=1;
    while(m!=0 && n!=0)
    {
        returnvalue=returnvalue*2;
        m--; n++;
    }
    return returnvalue;
}

void main()
{
    int m,n,result;
    m=3;
    n=-2;
    result=Recursion(m,n);
    printf("%d",result);
}

现在我怀疑是:

  1. 我读到要从递归更改为迭代,您需要使用堆栈并继续推送数据并稍后弹出。现在我不认为这样做。为什么?何时使用堆栈,何时不使用?
  2. 我的翻译版本是否正确?这个尾部是递归的,因为Recursion代码的来源是这样说的。
  3. 如何从递归版本更改为迭代版本。我真的需要一个很好的来源,我可以在这里学习。谷歌搜索没有多大帮助。

2 个答案:

答案 0 :(得分:3)

1)当有值要为每个呼叫保存时,您需要使用堆栈。在您的情况下,您不会在递归调用之后使用来自更深层递归调用的值,因此无需在堆栈上保存任何内容。

2)如果对它本身的调用是它做的最后一件事,那就是尾递归。作为@leppie评论,您在最后一次方法调用后正在执行2*

3)一般方法是使用堆栈;但是,在这种情况下,没有什么可以保存在堆栈上,所以你可以放弃它。

以下是一些示例,一个需要堆栈,另一个使用尾递归而不是。

void reverseCounting(int i, int n) {
    if (i >= n) return;
    reverseCounting(i + 1, n);
    cout << i << endl;
}

void counting(int i, int n) {
    if (i >= n) return;
    cout << i << endl;
    counting(i + 1, n);
}

// you could just count backwards, but this is a simple example.
void reverseCountingLoop(int i, int n) {
    // for C you can write you own stack to do the same thing.
    stack<int> stack; 
    //// if (i >= n) return;
    while (!(i >= n)) {
        //// reverseCounting(i + 1, n);
        // save i for later
        stack.push(i);
        // reuse i
        i = i + 1;
    }
    // unwind the stack.
    while (!stack.empty()) {
        //// cout << i << endl;
        i = stack.top(); stack.pop();
        cout << i << endl;
    }
}

void countingLoop(int i, int n) {
    //// if (i >= n) return;
    while (!(i >= n)) {
        //// cout << i << endl;
        cout << i << endl;
        //// counting(i + 1, n);
        // reuse i
        i = i + 1;
    }
    //// nothing after the recursive call.
}

答案 1 :(得分:0)

你应该知道尾递归比递归更优化。编译器知道这是一个递归,可能会改变一些事情。

相关问题