递归知识点和代码示例

1. 递归知识

  • 定义:
    一个函数直接或间接调用自己
  • 递归满足的三个条件:
    1)有一个明确的终止条件
    2)该函数处理的规模必须在递减
    3)调用自身 (或这个转化是可解的)
  • 递归的优缺点:
    优点:易于理解(数据规模在递减)
    缺点:速度慢;存储空间大(使用栈的结构,不断分配内存空间并执行压栈)(相对于循环来说)
  • 扩展:
    理论上循环能解决的,肯定可以转化为递归,但是这个过程是复杂的数学转化过程。递归能解决的不一定能转化为循环(所有的循环都可以用递归来实现,但是递归不能都用循环来实现)

2. 递归代码示例

(1) 1 到 100 的和

#include <stdio.h>

int sum(int n) {
    if (1 == n) {
        return 1;
    } else {
        return n + sum(n - 1);
    }
}

int main() {
    int n = 100;
    printf("sum = %d", sum(n));

    return 0;
}

(2) n 的阶乘

#include <stdio.h>

// 假定 n 的值大于或等于 0
long fn(long n) {
    if (1 >= n) {
        return 1;
    } else {
        return n * fn(n - 1);
    }
}

int main() {
    long n = 6;
    printf("%ld! = %ld\n", n, fn(n));

    return 0;
}

(3) 汉诺塔

#include <stdio.h>

void Hanoi(int n, char A, char B, char C) {
    if (1 == n) {
        printf("编号为 %d 的盘子的移动方向: %c --> %c\n", n, A, C);
    } else {
        Hanoi(n - 1, A, C, B);
        printf("编号为 %d 的盘子的移动方向: %c --> %c\n", n, A, C);
        Hanoi(n - 1, B, A, C);
    }
}

int main() {
    long n = 3;
    Hanoi(n, 'A', 'B', 'C');

    return 0;
}

/*
    伪算法:
        if 只有一个圆盘
            直接将圆盘从 A 柱子移动到 C 柱子上
        else
            先将 A 柱子上的 n-1 个盘子借助 C 移动到 B 上
            直接将圆盘从 A 柱子移动到 C 上
            最后将 B 柱子上的 n-1 个盘子借助 A 移动到 C 上

    算法复杂度:
        n=1         移动 1 次
        n=2         移动 3 次
        n=3         移动 7 次
        ...

        汉诺塔的复杂度是 2^n - 1 (问题很复杂,但真正解决问题的编码就只有三句)
*/
posted @ 2022-05-25 22:41  夏夜星空晚风  阅读(130)  评论(0编辑  收藏  举报