《C Primer Plus》读书笔记——递归

递归的原理

一个函数调用其本身,此调用过程为递归(recursion)。

递归的使用

举个栗子:

/*用来测试UpAndDown函数的驱动程序*/

#include <stdio.h>

void UpAndDown (int);

int main(void)
{
    UpAndDown(1);
    return 0;
}

void UpAndDown (int n)
{
    printf("Level %d: n location %p\n" , n, &n);
    if (n < 5)
        UpAndDown(n+1);
    printf("LEVEL %d: n location %p\n" , n, &n);
}

输出如下:

《C Primer Plus》读书笔记——递归

递归的基本原理

  • 每级递归都使用其私有变量(如例子中的n)

  • 每次函数调用都返回前一级(调用他那级)递归

  • 递归函数中,位于递归调用前的语句和各级被调函数具有相同执行顺序

  • 递归函数中,位于递归调用后的语句和各级被调函数具有相反执行顺序

  • 每级递归会从头执行而不是复制其函数代码,所以一般可代替循环语句。

  • 递归函数必须包含可以终止递归调用的语句(如if)。

尾递归

最简单的递归形式。

把递归调用语句放在函数结尾(return语句之前)。

举个栗子:
计算n的阶乘

long fact (int n) // 使用循环计算阶乘,占内存少,执行快
{
    long ans;

    for(ans = 1; n>1; n--)
        ans *= n;
    return ans;
}

long rfact (int n) // 使用递归计算阶乘,仅作尾递归展示、入门long ans;

    if(n > 0)
        ans = n * rfact(n-1);
    else
        ans = 1; //1.零的阶乘;2.结束递归。
    return ans;
}

递归和反向计算

将一个整数转换成二进制形式。

void ToBinary (unsigned long n) // 简单须存数组版递归
{
    int r;
    r = n % 2;
    if(n >= 2)
        ToBinary(n / 2);
    putchar('0' + r); //or: putchar(r ? '1' : '0')

    return;
}

递归的优缺点

优点
算法简单
缺点
占内存,难于阅读和维护

举个栗子:斐波那契数列:第一、二个数字都是1,而后续的每个数字是其前两个数字之和。1、1、2、3、5、8、13……

long Fibonacci (int n)
{
    if(n > 2)
        return Fibonacci(n-1) + Fibonacci(n-2);
    else
        return 1;
}

双重递归。
致命弱点:每级调用变量数以指数递增!

Something interesting …

main( )也可以被自身递归调用或其他函数调用,尽管用得少。

上一篇:asp.net简单实现禁用或启用页面中的某一类型的控件


下一篇:数据库管理系统(知识解集)