1.递归形象化:
在网上看到这样一句话,递归:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开它。若干次之后,你打开面前的门后,发现只有一间屋子,没有门了。然后,你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这你把钥匙打开了几扇门。
出自作者https://my.csdn.net/justloveyou_
2.递归的精髓是什么?
正如上面所描述的场景,递归就是有去(递去)有回(归来),如下图所示。“有去”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决,就像上面例子中的钥匙可以打开后面所有门上的锁一样;“有回”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点),一旦到达了这个临界点,就不用再往更小、更远的地方走下去。最后,从这个临界点开始,原路返回到原点,原问题解决。
3.举一个例子:
分析:(箭头表示运行顺序)
main()函数调用up_and_down(1) //return 0: 未执行 ↓ | 返回main()函数,继续执行return 0; |
进到函数定义处:void up_and_down(1) 此时int n =1 打印#1:level 1, 0x7ffd00648b6c 递归条件:n<4 =>真,调用自己:up_and_down(2) //打印#2:未执行 ↓ | ↑ 此时int n =1 打印#2: level 1,0x7ffd00648b6c
|
进到函数定义处:void up_and_down(2) 此时int n =2 打印#1:level 2, 0x7ffd00648b4c 递归条件:n<4 =>真,调用自己:up_and_down(3) //打印#2:未执行 ↓ | 此时int n =2 打印#2: level 2,0x7ffd00648b4c |
进到函数定义处:void up_and_down(3) 此时int n =3 打印#1:level 3, 0x7ffd00648b2c 递归条件:n<4 =>真,调用自己:up_and_down(4) //打印#2:未执行 ↓ | 此时int n =3 打印#2: level 3, 0x7ffd00648b2c |
进到函数定义处:void up_and_down(4) 此时int n =4 打印#1:level 4, 0x7ffd00648b0c 递归条件:n<4 =>假,不再满足条件,停止递归,开始归来 按照序执行打印#2:level 4, 0x7ffd00648b0c →→ | ↑ 返回上级调用,执行未执行的语句 |
运行结果:
4.用递归法写阶乘
分析:5!=5x4x3x2x1
main()函数 执行输入n,假设输入5 printf函数调用digui(5) //return 0: 未执行 | 返回main()函数,继续执行return 0; |
进到函数定义处:digui(5) 此时int n =5 递归条件:n>0 =>真, 执行temp=5*digui(4),调用自己:digui(4) //return temp:未执行 ↓ | ↑ 返回temp=5X4X3X2X1给digui(5) 再返回到上级调用处,执行未执行的语句 ↑ temp=5*digui(4)=5x4x3x2x1 |
进到函数定义处:digui(4) 此时int n =4 递归条件:n>0 =>真, 执行temp=4*digui(3),调用自己:digui(3) //return temp:未执行 ↓ | ↑ 返回temp=4X3X2X1给digui(4) 再返回到上级调用处,执行未执行的语句 ↑ temp=4*digui(3)=4x3x2x1 |
进到函数定义处:digui(3) 此时int n =3 递归条件:n>0 =>真, 执行temp=3*digui(2),调用自己:digui(2) //return temp:未执行 ↓ | ↑ 返回temp=3X2X1给digui(3) 再返回到上级调用处,执行未执行的语句 ↑ temp=3*digui(2)=3x2x1 |
进到函数定义处:digui(2) 此时int n =2 递归条件:n>0 =>真, 执行temp=2*digui(1),调用自己:digui(1) //return temp:未执行 ↓ | ↑ 返回temp=2X1给digui(2) 再返回到上级调用处,执行未执行的语句 ↑ temp=2*digui(1)=2x1 |
进到函数定义处:digui(1) 此时int n =1 递归条件:n>0 =>真, 执行temp=1*digui(0),调用自己:digui(0) //return temp:未执行 ↓ | ↑ 返回temp=1给digui(1) 再返回到上级调用处,执行未执行的语句 ↑ temp=1*digui(0)=1 |
进到函数定义处:digui(0) 此时int n =0 递归条件:n>0 =>假, 执行temp=1 执行return temp=1 →
| ↑ 返回temp=1给digui(0) 再返回到上级调用处,执行未执行的语句 |
运行结果