C++抽象编程——递归简介(2)——阶乘函数的执行分析

7.2 Thefactorial function.

单单一个收集筹款的例子,是不足以说明递归的强大的,为了深入理解递归,我们举一个更接近编程的例子。对大多数人来说,刚刚开始学习递归,最好的理解方式就是用简单的含有递归结构的数学函数来理解。而最常见的就是阶乘函数(factorial function)。我们先写个函数的原形

int fact(int n);

意思就是,输入整数n, 我们返回它的阶乘,比如n=5,返回 5*4*3*2*1=120; 当然 我们很容易用for循环来编写这个程序,而在递归的程序中,我们是没有这个for 循环的,但是我们同样实现了这个循环,我们要尝试从不同的方法解决这个问题。

7.2.1The recursive formulation of fact

只要我们认真观察,我们就可以发现,每一个阶乘都可以用更小的个阶乘表示,在数学上可以用下面公式表示

n! = n × (n – 1)!.

因此 4!=4 x 3!,而3!=3x2!.为了这个公式不能永远被分下去,数学上我们定义 0!= 1;所以,完整的数学定义可以写成下面的形式


这个定义就是递归的数学公式的定义。所以我们现在要找递归的基本特征——找到 n-1的阶乘(与原来问题一样的形式)。所以,我们可以通过同样的的定义来找到(n-1)!=(n-1)x(n-2)!。从这里,我们可以看到,严格的数学定义,为递归函数提供了模板(the practical impact of the mathematicaldefinition is that it provides a template for a recursive implementation.), 我们可以很轻松的用C++的编程语言来写出这个程序:

int fact(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}

当n=0的时候,就是simple cases,直接返回1;如果不是,那么程序通过计算(n-1)!来得到答案。这个程序就是直接按照阶乘的数学定义来写的,并且 fact 函数都含有同样的递归结构.

7.2.2 Tracing the recursive process

你会惊奇的发现,程序能运行,而且还可以输出正确答案,但是直接看程序,总会觉得程序少了点什么。尽管我们是严格按照数学的定义来写的程序,但是这个递归公式却是很难去区分去理解真正的计算在哪里发生。在上面的程序中,你能发现的就是fact函数再调用fact函数,一直这样下去。似乎有某些魔力促使你的计算机得出正确的答案。所以我们就一起去追踪一下递归的过程。比如我们一开始输入 n = 4

(1)  main 函数调用 fact 函数,那么程序就为fact 函数开辟一个框架(frame),类似于栈(stack)。

先判断n=0?,这里n=4,所以执行else 语句

n  * fact(n - 1).

(2)  要计算这一行的值,那么就要计算fact(n-1)的值。即


当调用fact(n-1)的时候,重复上面的步骤,n=4,所以n-1=3.

(3)  重复执行(2)步骤


(4)到达边界。这样下去,程序一定会调用到fact(1),此时fact(n-1)=fact(0),此时栈顶为


此时 程序就发生了改变,因为此时 n=0,程序就执行下面的语句

return 1;

(5)  将结果从栈顶返回。也就是执行逆过程,但是这个时候是带着确切的值的


最后一步 4x6=24,结果出来。







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值