将递归函数转换为尾递归

时间:2011-10-30 13:38:53

标签: c recursion

我有一个递归函数来计算所有值为20的节点,在循环双向链表中。我需要将其转换为尾递归函数以防止出现安全问题。请帮我一样。感谢

int count(node *start)
{
    return count_helper(start, start);
}
int count_helper(node *current, node *start)
{
    int c;
    c = 0;
    if(current == NULL)
        return 0;
    if((current->roll_no) == 20)
        c = 1;
    if(current->next == start) return c;
    return (c + count_helper(current->next, start));
}

2 个答案:

答案 0 :(得分:2)

这看起来像C. C实现通常不会识别尾递归,因此将函数转换为尾递归形式实际上并不会对您有所帮助。您需要将其更改为iterative

答案 1 :(得分:1)

将非尾递归函数转换为尾递归函数的一般方法是使用额外的累加器参数,通过递归调用对其进行当前评估。

在你的情况下,这很简单:

int count(node *start)
{
    return count_helper(start, start, 0);
}
int count_helper(node *current, node *start, int acc)
{
    int c;
    c = 0;
    if(current == NULL)
        return acc;
    if((current->roll_no) == 20)
        c = 1;
    if(current->next == start) return acc + c;
    return count_helper(current->next, start, acc + c);
}

我在这里做的主要更改是将额外的累加器参数int acc添加到count_helper定义中,并确保所有返回语句都包含acc(适当时)。现在,最终的return语句直接传回count_helper的结果,而不修改它;这现在是尾递归。

当递归调用的结果必须以非简单算术的方式组合时,它不那么简单。

然而,正如Ruakh所提到的,许多C编译器不想处理优化尾递归调用的麻烦,因为这根本不是C的风格。也许-O3可以做到吗?