递归的经典案例
hanoi塔
思路:
移动n层hanoi塔
①将n-1层先移动到B塔
②把A移动到C
③把n-1层从B塔移动到C塔
步骤①:
1)将n-2层先移动到C塔
2)把A移动到B
3)把n-2层从C塔移动到B塔
步骤1):
……
private static void hanoi(int n, String A, String B, String C) {
if (n == 1)
System.out.println(A + "->" + C);
else {
hanoi(n-1, A, C, B); // 移动层数n-1,源塔A,目标塔B
System.out.println(A + "->" + C);
hanoi(n-1, B, A, C); // 移动层数n-1,源塔B,目标塔C
}
}
递归与非递归的转换
消除递归的原因
1、递归执行需要系统提供隐式栈实现递归,因此效率低
2、递归算法是一次执行完成的,再处理某些问题时不合适
3、有些语言不支持递归(FOR-TRAN)
递归转换成非递归的方法
一类,简单递归问题的转换,对于尾递归和单向递归的算法,可用循环结构的算法替代;另一类,将递归中隐式的栈机制转换成用户控制的栈,利用栈来存储参数。
简单递归问题
求阶乘:n!
private static int fact(int n) { // 非递归
if (n == 0) // 0 != 1
return 1;
int fac = 1;
for (int i = 1; i <= n; i++) {
fac = fac * i;
}
return fac;
}
private static int fact(int n) { // 递归算法
if (n == 0)
return 1;
return n * fact(n-1);
}
计算斐波那契数列
F(n) = F(n-1) + F(n-2)
F(0) = 0
F(1) = 1
private static int F(int n) { // 非递归算法
if (n == 0 || n == 1)
return n;
int x = 1, y = 0;
int z = x;
for (int i = 2; i <= n; i++) {
x = z;
z = x + y;
y = x;
}
return z;
}
private static int F(int n) { // 递归算法
if (n == 0 || n == 1)
return n;
return F(n-1) + F(n-2);
}
用户控制栈的问题
中序和后序遍历二叉树的非递归算法
总结
递归算法:
从结果和函数的本身功能出发,思考Func(n)是从Func(n-1)怎么变换得来的,以及递归的截至条件,即n取某个值(一般n=0)时,函数得已知数
非递归算法
从特殊到一般,从n=0的情况开始,依次扩大n,结果根据运算规则运算结果也依次增大,直到求到n(类似于数学归纳法)
来源:CSDN
作者:ziyang0421
链接:https://blog.csdn.net/qq_41596915/article/details/104227787