简体   繁体   English

递归,尾递归和迭代

[英]Recursion, Tail Recursion and Iteration

Here is my code. 这是我的代码。

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);
}

Iteration 迭代

#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);
}

Now my doubts are: 现在我的疑问是:

  1. I read that to change from recursion to iteration, you need to use a stack and keep pushing the data and popping later. 我读到要从递归更改为迭代,您需要使用堆栈并继续推送数据并稍后弹出。 Now I don't see doing it here. 现在我看不到在这里做。 Why? 为什么? When is stack used, and when is it not? 什么时候使用堆栈,什么时候不使用?
  2. Is my translation to an iterative version correct here? 我的翻译版本在这里正确吗? Is this tail recursive because the source of the Recursion code said so. 这是尾递归吗,因为Recursion代码的来源是这样说的。
  3. How do I change from a recursive version to an iterative one. 我如何从递归版本更改为迭代版本。 I would really need a nice source from where I can study this. 我真的需要一个很好的资源来研究。 Googling did not help much. 谷歌搜索没有太大帮助。

1) You need to use a stack when there are values to save for each call. 1)当有每个呼叫要保存的值时,您需要使用堆栈。 In your case, you don't use the values from deeper recursive calls after the recursive invocation so there is nothing to save on the stack. 在您的情况下,您不会在递归调用之后使用更深层次的递归调用中的值,因此堆栈上没有任何内容可保存。

2) It's tail recursion if the call to itself is the last thing it does. 2)如果对自身的调用是最后的操作,则为尾递归。 As @leppie comments, you are performing a 2* after the last method call. 作为@leppie注释,您在最后一个方法调用之后执行2*

3) The general approach is to use a stack; 3)一般方法是使用堆栈; however, in this case, there is nothing to save on a stack, so you can drop it. 但是,在这种情况下,没有任何要保存的堆栈,因此可以将其删除。

Here are some examples, one which requires a stack and another which uses tail recursion and does not. 这是一些示例,一个示例需要堆栈,而另一个示例则使用尾部递归而不使用。

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.
}

You should know a tail recursion is more optimized than recursion. 您应该知道尾部递归比递归更优化。 Compiler know it's a recursion and may change some things. 编译器知道这是递归,并且可能会更改某些内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM