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 (问题很复杂,但真正解决问题的编码就只有三句)
*/