如何使用循环和堆栈来正确模拟递归?

时间:2017-09-28 15:02:10

标签: c loops recursion stack

(我不擅长英语,所以我的表达可能不太清楚和正确。)

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

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

解决Fibonacci序列的递归版本(只是递归的一个例子)。非常简单

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

堆栈由链表实现,相关功能非常简单。 它工作得很好,但我相信,我这样做的方式太迟了和困难。

我只是想知道如何更容易地做到这一点? (不是使用循环来解决Fibonacci而是模拟递归)

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

对于这样的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作为符号)。

1 个答案:

答案 0 :(得分:0)

我不明白为什么递归方法很糟糕但是如果你想用循环来做这件事我不应该太难了我有一些'几分'伪代码,你甚至不需要一个链表,这应该会减少你的程序的计算复杂性。

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

这只是我煮熟的东西,希望它可以帮到你。