累加的递归实现
同样是累加,递归实现的时间复杂度为O(),空间复杂度为O();而使用for循环的时间复杂度为O(),空间复杂度为O(),
#include<stdio.h>
/*递归累加
*系统将未运行完的reursiveAdd(paraN)压入栈中,等待recursiveAdd(paraN-1)算完
*/
int recursiveAdd(int paraN){
printf("Entering recursiveAdd(%d)\r\n",paraN);
if(paraN<=0){
printf("return 0\r\n");
return 0;
}
else{
printf("return recursiveAdd(%d)+%d\r\n",paraN-1,paraN);
return recursiveAdd(paraN-1)+paraN;
}
}
void recursiveAddTest(){
int n,num;
printf("---- RecursiveAddTest begins ----\r\n");
n=-1;
num=recursiveAdd(n);
printf("The result of recursiveAdd(%d) is %d\r\n",n,num);
n=1;
num=recursiveAdd(n);
printf("The result of recursiveAdd(%d) is %d\r\n",n,num);
n=5;
num=recursiveAdd(n);
printf("The result of recursiveAdd(%d) is %d\r\n",n,num);
printf("---- RecursiveAddTest ends ----\r\n");
}
int main(){
recursiveAddTest();
return 0;
}
运行结果
图解累加递归实现:以recursiveAdd(5)为例
1.要算recursiveAdd(5),需要算recursiveAdd(4),但recursiveAdd(5)还没算完,于是系统将其压入栈中(recursiveAdd(4)等同理)
2.算recursiveAdd(1)时需要算recursiveAdd(0),而recursiveAdd(0)返回了0,那么recursiveAdd(1)得以继续计算,返回recursiveAdd(0)+1,这时recursiveAdd(1)计算完毕,出栈;同理,recursiveAdd(2)等也得以继续计算,并相继出栈。
汉诺塔问题
#include<stdio.h>
void Hanoi(int paraN,char paraSource,char paraDestination,char paraTransit){
if(paraN<=0){
return;
}
else{
Hanoi(paraN-1,paraSource,paraTransit,paraDestination);
printf("%c -> %c\r\n");
Hanoi(paraN-1,paraTransit,paraDestination,paraSource);
}
}
void HanoiTest(){
int n;
printf("---- HanoiTest begins. ----\r\n");
printf("---------------n=1-------------\r\n");
n=1;
Hanoi(n,'A','B','C');
printf("---------------n=2-------------\r\n");
n=2;
Hanoi(n,'A','B','C');
printf("---------------n=3-------------\r\n");
n=3;
Hanoi(n,'A','B','C');
printf("---------------n=4-------------\r\n");
n=4;
Hanoi(n,'A','B','C');
printf("---- HanoiTest ends. ----\r\n");
}
int main(){
HanoiTest();
return 0;
}
运行结果
---- HanoiTest begins. ----
---------------n=1-------------
B -> C
---------------n=2-------------
C -> B
A -> C
B -> A
---------------n=3-------------
B -> C
A -> B
C -> A
B -> C
A -> B
C -> A
B -> C
---------------n=4-------------
C -> B
A -> C
B -> A
C -> B
A -> C
B -> A
C -> B
A -> C
B -> A
C -> B
A -> C
B -> A
C -> B
A -> C
B -> A
---- HanoiTest ends. ------------------------------------
Process exited after 0.04675 seconds with return value 0
请按任意键继续. . .
手动函数调用过程图:
以n=3为例,
Hanoi(3,s,d,t)需要执行三步:1.执行Hanoi(2,s,t,d) 2.printf(s->d) 3.执行Hanoi(2,t,d,s);
但执行1.Hanoi(2,s,t,d)时也需要执行三步:1.执行Hanoi(1,s,d,t) 2.printf(s->t) 3.执行Hanoi(2,d,t,s);
所以Hanoi(3,s,d,t)被系统压入栈中,等待1.Hanoi(2,s,t,d)2.printf(s->d) 3.执行Hanoi(2,t,d,s);完毕执行
Hanoi(2)同理,需要等Hanoi(1),所以Hanoi(2)也会被压入栈中.....
Hanoi的时间复杂度和空间复杂度:
时间复杂度:O(n)=2^n
空间复杂度:O(n)=n
因为栈的原因,有空间复用,因此hanoi的空间复杂度远小于时间复杂度
心得体会:
手动跟着老师的代码将函数调用过程写一遍,会对Hanoi递归调用的理解好得多
使用递归有些时候的确时间复杂度会好很多,但是它理解很困难,并且不好对变量进行追踪,这也许就是为什么老师说出现了递归多半都是高级程序的原因吧