本文将详细介绍在C++中的递归.

定义:递归是一个函数调用它自身的过程,但由于可能会有无限次的调用,栈可能会溢出,所以递归必须要有终止条件.

在C++中,递归分为两种类型:

  • 运行时递归(Run-Time Recursion):与C语言类似
  • 编译时递归(Compile-Time Recursion): 用C++提供的模板元编程,不给出翻译,请参照原文

每一种分类可以细分为以下5种类型

  • 线性递归(Linear Recursion)
  • 二分递归(Binary Recursion)
  • 尾递归(Tail Recursion)
  • 互递归(Mutual Recursion)
  • 嵌套递归(Nested Recursion)

一、线性递归

该递归最常用,它通过一种简单的方式调用自己,并通过一个终止条件终止自身.这个调用过程称之为“缠绕(Winding)”,当函数返回给调用者时称之为“解除缠绕(Un-Winding)”。递归终止条件是我们已知的基础条件.

例子:计算阶乘

int Fact(long n)
{
    if (0 > n)
        return -1;
    if (0 == n)
        return 1;
    else
    {
        return (n* Fact(n - 1));
    }
}

二、二分递归

二分递归是一个函数一次调用两次而不是一次调用一次的过程。它主要用于数据结构中,如树的遍历、查找高度、合并等操作。

例子:斐波那契数列

int FibNum(int n)
{
    // Base conditions
    if (n < 1)
        return -1;
    if (1 == n || 2 == n)
        return 1;

    // Recursive call by Binary Method
    return FibNum(n - 1) + FibNum(n - 2);   
}

三、尾递归

四、互递归

函数相互调用。假设FunA调用FunB, FunB递归调用FunA。这实际上不是递归的,但它和递归是一样的。所以你可以说不支持递归调用的编程语言,相互递归可以应用在那里来满足递归的要求。基本条件可以应用于任意一个或多个函数或所有函数。

例子:判断偶数或者奇数

bool IsOddNumber(int n)
{
    // Base or Termination Condition
    if (0 == n)
        return 0;
    else
        // Recursive call by Mutual Method
        return IsEvenNumber(n - 1);
}
bool IsEvenNumber(int n)
{
    // Base or Termination Condition
    if (0 == n)
        return 1;
    else
        // Recursive call by Mutual Method
        return IsOddNumber(n - 1);
}

五、嵌套递归

它和所有递归非常不同。除嵌套递归外,所有递归都可以转换为迭代(循环)。你可以通过阿克曼函数的例子来理解这个递归。

int Ackermann(int x, int y)
{
    // Base or Termination Condition
    if (0 == x)
    {
        return y + 1;
    }
    // Error Handling condition
    if (x < 0 || y < 0)
    {
        return -1;
    }
    // Recursive call by Linear method 
    else if (x > 0 && 0 == y)
    {
        return Ackermann(x - 1, 1);
    }
    // Recursive call by Nested method
    else
    {
        return Ackermann(x - 1, Ackermann(x, y - 1));
    }
}

原文链接:https://www.dreamincode.net/forums/topic/51296-types-of-recursion/