繁体   English   中英

递归,尾递归和迭代

[英]Recursion, Tail Recursion and Iteration

这是我的代码。

递归:

#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. 我如何从递归版本更改为迭代版本。 我真的需要一个很好的资源来研究。 谷歌搜索没有太大帮助。

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

您应该知道尾部递归比递归更优化。 编译器知道这是递归,并且可能会更改某些内容。

暂无
暂无

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

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