【问题标题】:How to use loop and stack to simulate recursion correctly?如何正确使用循环和堆栈来模拟递归?
【发布时间】:2018-03-10 09:22:45
【问题描述】:

(我的英文不太好,所以表达可能不太清楚正确。)

我想通过循环和堆栈来模拟递归。

我的目标不是关于如何提高性能,因为解决斐波那契的原始递归方法也非常无效。并且模拟几乎不可能有更好的性能。我想知道如何将递归更改为循环和堆栈。

求解斐波那契数列的递归版本(只是递归的一个例子)。很简单

int fib(int i)
{
    if (i == 0)
        return 0;
    if (i == 1)
        return 1;
    return fib(i - 1) + fib(i - 2);
}

这是我的递归模拟

int fib2(int a)
{
    Stack *stack = NULL;
    int temp = -1;
    int i[3] = {a, -1, -1};
    stack = stack_push(stack, i);
    while(!stack_empty(stack))
    {
        int *top = stack_top(stack);
        if (temp != -1 && top[1] == -1)
        {
            top[1] = temp;
            temp = -1;
        }
        else if(temp != -1 && top[2] == -1)
        {
            top[2] = temp;
            temp = -1;
        }
        if (top[0] == 0)
        {
            stack = stack_pop(stack);
            temp = 0;
            continue;
        }
        else if(top[0] == 1)
        {
            stack = stack_pop(stack);
            temp = 1;
            continue;
        }
        else
        {
            int j[3] = {top[0], -1, -1};
            if (top[1] == -1)
            {
                j[0] = top[0] - 1;
                stack = stack_push(stack, j);
            }
            else if (top[2] == -1)
            {
                j[0] = top[0] - 2;                
                stack = stack_push(stack, j);
            }
            else
            {
                temp = top[1] + top[2];
                stack = stack_pop(stack);
            }
            continue;
        }
    }
    return temp;
}

栈是用链表实现的,相关功能很简单。 它运行良好,但我认为我这样做的方式太慢且太难了。

我只是想知道如何才能更轻松地做到这一点? (不是用循环来求解斐波那契而是模拟递归)

我真正关心的是如何处理多个递归函数调用。

对于 1 个这样的函数调用。

int sum(int i)
{
    if (i == 0)
        return 0;
    return i + sum(i - 1);
}

使用循环和堆栈很容易模拟。也很有效。

int sum2(int a)
{
    Stack *stack = NULL;
    while (a > 0)
    {
        stack = stack_push(stack, a);
        a--;
    }
    int i = 0;
    while (!stack_empty(stack))
    {
        i += stack_top(stack);
        stack = stack_pop(stack);
    }
    return i;
}

但是对于超过 1 个电话,我所知道的只是使用这种愚蠢的方式来做(放一个 -1 作为标志)。

【问题讨论】:

  • 当然比直接使用递归要慢,甚至比使用循环还要慢。你期待什么?
  • 我希望有一种正确的方法来模拟递归,因为 c 中的堆栈大小在默认情况下是有限的。因此,我想改用堆。这只是一种练习。
  • 量化“它太迟钝和无效”与什么相比?需要改进多少?没有看到Stack, stack_pop(), stack_pop(), ...,这个帖子是不必要的模糊。
  • 如果可行,请坚持使用您的解决方案。真的有那么慢吗?

标签: c loops recursion stack


【解决方案1】:

我不明白为什么递归方法不好,但如果你想用循环来做到这一点,它应该不会太难我有一些你没有的“排序”伪代码甚至需要一个链表,这应该会降低程序的计算复杂度。

int main() {
  int fib_max = 10;

  int node_1 = 0;
  int node_2 = 0;
  int node_s = 0;

  for ( int n = 0; n < fib_max; n ++)
    {
      if (node_2 == 0)
    node_2 = 1;

      node_s = node_2 + node_1;
      node_1 = node_2;
      node_2 = node_s;
    }
}

这是我自己编出来的,希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2014-12-10
    • 2014-01-17
    • 2014-06-12
    • 2021-01-18
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2021-12-21
    • 2015-04-04
    相关资源
    最近更新 更多