期末复习_chap6 递归算法设计(1)
递归算法设计

递归算法设计基本概念在定义⼀个函数时,出现调⽤⾃⾝函数的,称为递归(recursion)。
如果⼀个递归函数,最后⼀条语句是递归调⽤语句,则称这种递归调⽤为尾递归(tail recursion)。
⼀个递归模型通常有两部分构成:初值(递归出⼝)和递归体。
递归的使⽤条件递归的数学定义,⽐如斐波那契数列:F(1)=F(2)=1,F(n)=F(n−1)+F(n−2),n≥3F(1)=F(2)=1,F(n)=F(n−1)+F(n−2),n≥3。
递归的数据结构,出现了指向⾃⾝的指针或者引⽤,如链表、树、图等。
递归的求解⽅法。
⽐如经典的汉诺塔问题。
递归函数的时间空间求解递归函数的时间通常需要根据问题解出相应的递归式。
对于形如归并排序的分治算法,其递归式通常形如T(n)=aT(bn)+f(n)T(n)=aT(bn)+f(n),通常可以使⽤主定理(《算法导论》 p53)来求解。
⼀般情况的递归算法的时间分析可能⽐较困难,需要详细了解递归的执⾏过程。
⽐如动态规划法和暴⼒算法都可以使⽤递归,但是他们的时间复杂度有显著差异。
递归的空间复杂度除了要考虑分配的临时变量之外,还需要考虑递归的深度(虽然使⽤的是栈空间,也要将其计算在内。
)递归程序⾮递归化对于递归的实现机理,需要理解现代CPU的栈帧模型。
栈帧保存了当前函数状态的相关信息。
当函数调⽤另⼀个函数时,它将保存临时变量等信息,同时为被调⽤的函数开辟另⼀个帧。
因此递归函数调⽤,每⼀层是不会相互影响的。
通常情况下递归是由编译器⾃动实现,然⽽系统的栈空间是固定的,对于递归深度较⼤的情况,可能会出现栈溢出(stack overflow),因此这时候必须⽤栈的数据结构⼿动模拟栈帧,来实现递归程序⾮递归化。
具体操作来说,就是在原来递归出现之前,利⽤栈保存前⼀层的环境,然后切换到下⼀层;在原来递归返回到调⽤函数时,将栈顶元素出栈,得到被保存的环境。
⼀个例⼦可以参考之前第3章综合练习的⼀道题⽬字符串解码(Decode String)。
递归 设计模式

递归设计模式
递归是一种设计模式,它在编程和计算机科学领域中经常被使用。
递归指的是在解决问题时,将问题分解为一个或多个相似但规模较小的子问题,并通过在子问题上应用相同的方法来解决问题。
递归设计模式包括以下关键要点:
1.基本案例(Base Case):递归算法必须有一个或多个基本案例,这些基本案例是递归的终止条件。
当问题达到基本案例时,递归停止,不再继续分解。
2.递归案例(Recursive Case):在递归设计模式中,问题被分解为一个或多个子问题,这些子问题通常与原始问题相似但规模较小。
递归算法在子问题上使用相同的方法,以逐步解决问题。
3.递归调用(Recursive Call):在递归算法中,函数或方法会调用自身,以处理子问题。
这是递归的核心部分。
递归设计模式通常应用于问题具有自相似性或可以被分解为相似子问题的情况。
经典的示例包括计算斐波那契数列、二叉树遍历、计算阶乘等。
递归设计模式可以使代码更加简洁和易于理解,但需要小心处理终止条件,以避免无限递归。
示例:计算斐波那契数列的递归实现
```python
def fibonacci(n):
if n<=0:
return0
elif n==1:
return1
else:
return fibonacci(n-1)+fibonacci(n-2)
```
在上述示例中,`fibonacci`函数通过递归方式计算斐波那契数列的值。
递归调用在处理子问题(n-1和n-2)上使用相同的方法。
递归终止条件为n=0和n=1,它们是基本案例。
递归求最大值的算法设计

递归求最大值的算法设计递归是一种常见且重要的算法思想,它可以将一个大问题划分为若干个相同或相似的子问题,通过解决子问题来解决原问题。
在算法设计中,递归经常被用来解决需要重复执行某个操作的问题。
本文将介绍一种使用递归求解最大值的算法设计。
最大值是指一组数中的最大值,也就是说,我们需要找到一组数中的最大的那个数。
通过递归思想,我们可以将原问题划分为子问题,然后通过解决子问题来解决原问题。
我们需要定义一个函数来实现递归求解最大值的功能。
我们将这个函数命名为`find_max`。
这个函数的输入参数是一个整数数组`nums`和两个整数`start`和`end`,表示数组的起始索引和结束索引。
函数的返回值是数组中的最大值。
接下来,我们需要考虑递归的终止条件。
当数组中只有一个元素时,这个元素就是最大值,我们可以直接返回它。
所以,当`start`等于`end`时,我们可以直接返回`nums[start]`。
然后,我们需要将原问题划分为两个子问题。
我们可以将数组分为两半,分别求解左半部分的最大值和右半部分的最大值,然后将两个最大值进行比较,取其中较大的那个作为最终的结果。
为了实现这个功能,我们可以将数组分为两个部分,中间的索引可以通过`(start + end) // 2`来计算得到。
接下来,我们可以使用递归调用来解决子问题。
我们分别对左半部分和右半部分调用`find_max`函数,分别得到左半部分的最大值和右半部分的最大值,并将它们进行比较,取其中较大的那个作为最终的结果。
我们将递归求解最大值的结果返回给调用者。
这样,整个递归过程就完成了。
通过以上的算法设计,我们可以使用递归来求解一组数中的最大值。
这种算法设计思想简洁明了,代码逻辑清晰。
同时,递归求解最大值的算法设计可以方便地应用于实际问题中,例如在查找一组数据中的最大值时,可以使用该算法来提高代码的可读性和可维护性。
需要注意的是,递归求解最大值的算法在最坏情况下的时间复杂度为O(n),其中n表示数组的长度。
06递归算法PPT课件

递归的定义
若一个对象部分地包含它自己, 或用它自己给自 己定义, 则称这个对象是递归的;若一个过程直接地 或间接地调用自己, 则称这个过程是递归的过程。
递归的定义
直接递归 fun_a() {… fun_a() … }
间接递归 fun_a() {… fun_b() …}
fun_b() {… fun_a() …}
c1, c2,……,cm是若干个可以直接(用非递归方法)解决的问题, g是一个非递归函数,反映了递归问题的结构。
递归模型
例如,阶乘函数 递归出口
1,
当n0时
n! n(n1)!, 当n1时
递归体
ห้องสมุดไป่ตู้
递归的执行过程
实际上,递归是把一个不能或不好直接求解的 “大问题”转化为一个或几个“小问题”来解决,再 把这些“小问题”进一步分解成更小的“小问题”来 解决,如此分解,直至每一个“小问题”都可以直接 解决(此时分解到递归出口)。
递归调用执行过程:
... ...
main() x=17
bn=bSearch(a,x,0,7)
...
bn=bSearch(a,x,0,7)
mid=3 bn=bSearch(a,x,4,7)
...
4
...
return(bn=bSearch(a,x,4,7))
mid=5
bn=bSearch(a,x,4,4)
6.1 递归的概念
若一个算法直接地或间接地调用自己本身,则称 这个算法是递归算法。
1.问题的定义是递归的
例如:阶乘函数的定义
1
当n=0时
n=
n*(n-1) 当n>0时
2. 问题的解法存在自调用 例如:折半查找算法
递归算法知识点总结

递归算法知识点总结一、基本概念递归算法的基本概念是基于递归函数的思想。
递归函数是一个调用自身的函数。
递归算法通常可以分为两种类型:简单递归和复杂递归。
简单递归是指在递归函数中直接调用自身,而复杂递归则是指在递归函数中可能会有多个递归调用。
递归算法通常用于解决可以分解为若干子问题的问题,这种方法通常可以更加简洁地解决问题,但同时也可能会带来一些计算复杂度的问题。
递归算法的设计通常包括以下几个步骤:1. 确定基本情况:在设计递归函数时,通常需要确定一个或多个基本情况。
基本情况通常是指在递归函数中不需要再次调用自身的情况。
2. 确定递归情况:在设计递归函数时,需要确定一个或多个递归情况。
递归情况通常是指在递归函数中需要调用自身的情况。
3. 确定递归方式:当确定了递归函数的基本情况和递归情况之后,就需要确定递归函数的调用方式。
通常有两种方式:直接递归和间接递归。
4. 编写递归函数:根据确定的基本情况、递归情况和递归方式,编写递归函数。
5. 测试递归函数:编写递归函数后,需要对递归函数进行测试,确保递归函数能够正确地解决问题。
二、递归算法的原理递归算法的原理是基于递归函数的调用。
当一个递归函数被调用时,它会将自身的执行环境保存到栈中,并且在栈中分配一些空间。
在递归函数中,如果有一些局部变量,这些变量会在栈中分配空间。
随着递归函数的深入调用,栈中的空间也会不断增加。
在递归函数的执行过程中,通常需要考虑递归栈的压栈和出栈操作。
在递归函数被调用时,会执行一些初始化操作,并将递归参数保存到栈中。
在递归函数中,如果遇到递归情况,会再次调用自身,并且将自身的执行环境保存到栈中。
在递归函数的执行过程中,如果遇到基本情况,就会结束当前递归调用,并且从栈中释放空间。
递归算法的原理是基于递归函数的深度调用的。
当递归函数被调用时,会执行一些初始化过程,并将递归参数保存到栈中。
当递归函数执行完毕后,会从栈中释放空间。
在递归函数的执行过程中,栈中的空间会不断增加和释放。
递归算法详解完整版

递归算法详解完整版递归算法是一种重要的算法思想,在问题解决中起到了很大的作用。
它通过将一个大问题划分为相同或类似的小问题,并将小问题的解合并起来从而得到大问题的解。
下面我们将详细介绍递归算法的定义、基本原理以及其应用。
首先,我们来定义递归算法。
递归算法是一种通过调用自身解决问题的算法。
它通常包括两个部分:基础案例和递归步骤。
基础案例是指问题可以被直接解决的边界情况,而递归步骤是指将大问题划分为较小问题并通过递归调用自身解决。
递归算法的基本原理是"自顶向下"的思维方式。
即从大问题出发,不断将问题划分为较小的子问题,并解决子问题,直到达到基础案例。
然后将子问题的解合并起来,得到原始问题的解。
递归算法的最大特点是简洁而优雅。
通过将复杂问题分解为简单问题的解决方式,可以大大减少代码的复杂程度,提高程序的效率和可读性。
但是递归算法也有一些缺点,包括递归深度的限制和复杂度的不确定性。
过深的递归调用可能导致栈溢出,而不合理的递归步骤可能导致复杂度过高。
递归算法有许多应用场景,我们来介绍其中一些典型的应用。
1.阶乘问题:计算一个数的阶乘。
递归算法可以通过将问题划分为更小的子问题来解决。
例如,n的阶乘可以定义为n乘以(n-1)的阶乘。
当n 等于1时,我们可以直接返回1作为基础案例。
代码如下:```int factorial(int n)if (n == 1)return 1;}return n * factorial(n - 1);```2.斐波那契数列问题:求斐波那契数列中第n个数的值。
斐波那契数列的定义是前两个数为1,然后从第三个数开始,每个数都是前两个数的和。
递归算法可以通过将问题划分为两个子问题来解决。
当n等于1或2时,直接返回1作为基础案例。
代码如下:```int fibonacci(int n)if (n == 1 , n == 2)return 1;}return fibonacci(n - 1) + fibonacci(n - 2);```3.二叉树问题:对于给定的二叉树,递归算法可以通过递归调用左子树和右子树的解来解决。
递归算法步骤

递归算法步骤
递归算法是一种通过自身调用来解决问题的算法。
其步骤可以简述为以下几点:
1. 定义递归函数:首先需要定义一个递归函数,该函数负责解决具体的问题。
函数的参数通常包括输入数据和递归所需的其他参数。
2. 设定递归终止条件:在递归函数中,需要设定一个终止条件,当满足这个条件时,递归将停止并返回结果。
这是确保递归不会无限循环的重要部分。
3. 处理基本情况:在递归函数中,需要考虑到一些基本情况,这些情况通常可以直接求解,而不需要继续进行递归。
在这些情况下,可以直接返回结果,从而减少递归的次数。
4. 缩小问题规模:在递归函数中,需要将原始问题划分成更小的子问题。
通过缩小问题规模,可以将原始问题转化为更简单的形式,并且递归地解决这些子问题。
5. 调用递归函数:在递归函数中,需要调用自身来解决子问题。
通过递归调用,可以反复地将问题分解为更小的子问题,直到达到终止条件为止。
6. 整合子问题的解:在递归函数中,需要将子问题的解整合起来,得到原始问题的解。
这通常涉及到对子问题的解进行合并、计算或其他操作。
7. 返回结果:最后,递归函数需要返回结果。
这个结果可
以是最终的解,也可以是在每次递归调用中得到的中间结果。
需要注意的是,在使用递归算法时,要确保递归能够正确地终止,并且要注意避免出现无限递归的情况。
另外,递归算法的效率通常较低,因此在设计算法时要考虑到时间和空间复杂度的问题。
递归算法模板 -回复

递归算法模板-回复什么是递归算法?递归算法是一种解决问题的方法,其基本思想是将一个大问题拆分成一个或多个小问题,并通过递归地调用自身来解决这些小问题。
在递归算法中,我们将问题的规模逐渐缩小,直至达到可以直接求解的基本情形。
递归算法常常使用递归函数来实现。
通过递归算法,我们可以简洁地解决一些复杂的问题。
递归算法模板是什么?递归算法模板是一种通用的框架,可以用于许多需要使用递归算法解决的问题。
它由以下几个步骤组成:1. 定义基本情形:在递归过程中,我们总是希望问题的规模能够逐渐缩小,直至达到可以直接求解的基本情形。
因此,我们首先需要定义这个基本情形,即不再需要递归调用的情况。
2. 缩小问题规模:在递归算法中,我们将一个大问题拆分成一个或多个小问题。
我们需要通过调用递归函数来解决这些小问题。
在这一步骤中,我们需要确定如何将大问题规模缩小为小问题规模。
3. 调用递归函数:在这一步骤中,我们调用递归函数来解决小问题。
递归函数将继续递归地调用自身,直至达到基本情形。
4. 组合结果:在得到小问题的解之后,我们需要将这些解组合起来,得到大问题的解。
这个递归算法模板的核心思想是将大问题分解成小问题,通过递归地解决这些小问题,最终求解整个大问题。
递归算法模板的应用举例为了更好地理解递归算法模板的应用,我们可以通过一个简单的例子来说明。
假设我们需要计算一个数组中所有元素的和。
1. 定义基本情形:当数组为空时,和为0。
2. 缩小问题规模:我们可以将数组分成第一个元素和剩余元素两部分。
其中,第一个元素可以看作是小问题的解,剩余元素构成一个新的更小的问题。
3. 调用递归函数:我们通过调用递归函数来计算剩余元素的和。
4. 组合结果:将第一个元素与剩余元素的和相加,即为整个数组的和。
递归算法实际上是通过将一个大问题拆分成一个或多个类似的小问题,来简化问题的求解过程。
递归函数不断地调用自身,直至达到基本情形,然后将小问题的解逐步组合起来,求解整个大问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6
1.递归的概念 递归的概念
递归可以分为直接递归和间接递归两种。 递归可以分为直接递归和间接递归两种。 直接递归:函数体里面发生对自己的调用; 直接递归:函数体里面发生对自己的调用; 间接递归:函数A调用函数B 而函数B 间接递归:函数A调用函数B,而函数B又直接或 间接地调用函数A 间接地调用函数A。
– 就象剥一颗圆白菜,从外向里,一层层剥下来,到 就象剥一颗圆白菜,从外向里,一层层剥下来, 了菜心,就不再继续剥了。 了菜心,就不再继续剥了。
16
2.递归过程 递归过程
• 回归阶段: 回归阶段: 回归阶段,当获得最简单情况的解后, – 在回归阶段,当获得最简单情况的解后,逐 级返回, 级返回,依次得到稍复杂问题的解 。如在得 的解后, 到f(1)的解后,又依次得到 的解后 又依次得到f(2)、f(3)…直到 、 … f(6)的值。 的值。 的值 – 就像将剥下来的白菜叶又从里往外一叶一叶 合起来,直到最外层菜叶。 合起来,直到最外层菜叶。
函数--递归 第五章 函数 递归
选自: 选自: 章以及第16章的 《计算机导论与程序设计基础》 第6章以及第 章的 计算机导论与程序设计基础》 章以及第 章的16.1 程序设计教程》 《C程序设计教程》 5.13~5.15 程序设计教程
1
提纲
1. 递归的概念 2. 递归过程 3. 递归程序设计
2
1.递归的概念 递归的概念
3
1.递归的概念 递归的概念
例:编写一个函数fac,计算阶乘 编写一个函数 ,计算阶乘n! 按过去的迭代算法,该函数可以写成: 按过去的迭代算法,该函数可以写成: int fac(int n) { int i, p; p = 1; for(i = 2; i <= n; i++) p = p * i; return p; }
12
2.递归过程 递归过程 回 顾
被调用函数中 的数据 现场信息, 现场信息,用 于调用结束能 正确返回
函数调用过程
13
5.printf(“%d”,f(i)); 8.int f(int n) 9.{ 10. if(n==0) 11. return 1; 12. else 13. return n*f(n-1); 14.}
8
提纲
1. 递归的概念 2. 递归过程 3. 递归程序设计
9
Байду номын сангаас
2.递归过程 递归过程
• 求f(2)的 ( ) 递归调用过程? 递归调用过程?
#include <stdio.h> int f(int); main() { int i = 2; printf(“%d”,f(i)); system(“pause”); } int f(int n)//递归函数:求n! 递归函数: 递归函数 { if(n == 0) return 1; else return n * f(n - 1); }
4
1.递归的概念 递归的概念
现在换一个角度考虑, !不仅是1× × × 现在换一个角度考虑,n!不仅是 ×2×3×…×n, 还可以定义成: 还可以定义成: 设 f(n)=n! 1 当n=0 =
int f(int n) { if(n==0) return 1; else return n*f(n-1); } n! = 则 f(n) = 1 当n=0 = n×(n-1)! 当n>0 × - > n×f (n-1) 当n>0 > ×
18
2.递归过程 递归过程
• 递归算法的出发点不放在初始条件上,而放在求解的 递归算法的出发点不放在初始条件上, 算法的出发点不放在初始条件上 目标上, 目标上,是从所求的未知项出发逐次调用本身的求解 过程,直到递归的边界(即初始条件)。 过程,直到递归的边界(即初始条件)。 • 就求阶乘而言,读者会认为递归算法可能是多余的, 就求阶乘而言,读者会认为递归算法可能是多余的, 费力而不讨好。 费力而不讨好。但许多实际问题不可能或不容易找到 显而易见的迭代关系, 显而易见的迭代关系,这时递归算法就表现出了明显 的优越性。 的优越性。 • 下面我们将会看到,递归算法比较符合人的思维方式, 下面我们将会看到,递归算法比较符合人的思维方式, 逻辑性强,可将问题描述得简单扼要, 逻辑性强,可将问题描述得简单扼要,具有良好的可 读性,易于理解,许多看来相当复杂, 读性,易于理解,许多看来相当复杂,或难以下手的 问题, 问题,如果能够使用递归算法就会使问题变得易于处 理。
回 归 阶 段
返回
15
[回归阶段]
2.递归过程 递归过程
• 可见,递归算法的执行过程分递推和回归两个阶 可见,递归算法的执行过程分递推和回归两个阶 递推 当递推时, 段。当递推时,并没有求值的计算操作,实际的 当递推时 并没有求值的计算操作, 计算操作是在回归过程实现的。 计算操作是在回归过程实现的。 • 递推阶段: 递推阶段: – 递推阶段是个不断简化问题的阶段:把对较复 递推阶段是个不断简化问题的阶段: 阶段是个不断简化问题的阶段 杂问题(规模为n)的求解转化为比原问题简单 杂问题(规模为 )的求解转化为比原问题简单 一些的问题(规模小于n) 例如对f 一些的问题(规模小于 )的求解 。例如对 (6) 的求解转化为f(5)的求解, 对f(5)的求解转化为 的求解, 的求解转化为 的求解 的求解转化为 f(4)的求解…直到转化为对 的求解。 的求解… 的求解。 的求解 直到转化为对f(0)的求解 – 当递推到最简单的不用再简化的问题时,递推 当递推到最简单的不用再简化的问题时 最简单的不用再简化的问题时, 终止。 函数中 函数中, 的情况。 终止。如f函数中,n==0的情况。 的情况
5
6
14
递归深度 0(主程序) 1
f(n) f(6) f(6)=6×f(5)
求f(6)的递归调用过程 的递归调用过程
6×120=720 5×24=120 4×6=24 3×2=6 2×1=2 1×1=1
递
2 3 4 5 6
推 阶 段
f(5)=5×f(4) f(4)=4×f(3) f(3)=3×f(2) f(2)=2×f(1) f(1)=1×f(0) f(0)=1 (返回) [递推阶段]
调用
真
0== ==0 ==
假
f(0) =1
计算 2*f(1)
计算 1*f(0)
④
返回2 返回
返回 1
③
返回 1
11
2.递归过程 递归过程
• 请思考: 请思考: – 发出 发出f(2)调用时,将2赋值给形参 。然后发出 调用时, 赋值给形参n。然后发出f(1)调用,将 调用, 调用时 赋值给形参 调用 1赋值给形参 。接着发出 赋值给形参n。接着发出f(0)调用,将0赋值给形参 。后 调用, 赋值给形参 赋值给形参n。 赋值给形参 调用 来赋给形参n的值会不会覆盖原来赋给 的值(如值1覆盖 的值会不会覆盖原来赋给n的值 来赋给形参 的值会不会覆盖原来赋给 的值(如值 覆盖 原来的值2)?为什么? )?为什么 原来的值 )?为什么? 不会,每一次函数调用会在栈顶分配新的活动记录。 -不会,每一次函数调用会在栈顶分配新的活动记录。 – 对递归函数的每一次调用结束返回时,为何能回到调用前 对递归函数的每一次调用结束返回时, 的程序运行状态? 调用结束返回f(2)时 的值为2。 的程序运行状态?如f(1)调用结束返回 时,n的值为 。 调用结束返回 的值为 -函数访问的永远是栈顶的活动记录。当f(1)调用结束时, 函数访问的永远是栈顶的活动记录。 调用结束时, 调用结束时 位于栈顶的f(1)的活动记录将出栈,此时位于栈顶的将是 的活动记录将出栈, 位于栈顶的 的活动记录将出栈 f(2)的函数活动记录。 的函数活动记录。 的函数活动记录
根据以上数学 定义,函数f能 定义,函数 能 否写成左边所 示?函数能否 调用自身? 调用自身?
答案是肯定的。 答案是肯定的。 C系统会保证 系统会保证 调用过程的正 确性, 确性,这就是 递归! 递归!
5
递归的定义: 递归的定义: int f(int n) 从程序书写来看,在定义一个 { 从程序书写来看, 函数时, 函数时,若在函数的功能实现部 if(n == 0) 分又出现对它本身的调用, 分又出现对它本身的调用,则称 return 1; 该函数是递归的或递归定义的。 该函数是递归的或递归定义的。 else return n * f(n-1); 从函数动态运行来看, 从函数动态运行来看,当调用 一个函数A时 在进入函数A且 一个函数 时,在进入函数 且 } 还没有退出(返回)之前, 还没有退出(返回)之前,又再 一次由于调用A本身而进入函数 一次由于调用 本身而进入函数 A,则称之为函数 的递归调用。 的递归调用。 ,则称之为函数A的递归调用
• 递归算法在可计算性理论中占有重要地位,它 递归算法在可计算性理论中占有重要地位, 是算法设计的有力工具, 是算法设计的有力工具,对于拓展编程思路非 常有用。 常有用。就递归算法而言并不涉及高深数学知 识,只不过初学者要建立起递归概念不十分容 易。 • 我们先从一个最简单的例子导入。 我们先从一个最简单的例子导入。
调用f(0) 调用
n n n i
0 /*13*/ 1 /*13*/ 2 /*5*/ 2
f(0)返 返 回值1 回值
n n i
1 /*13*/ 2 /*5*/ 2
1. int f(int); 调用 调用f(1) 2. main() 1 n 调用f(2) 调用 { /*13*/ 3. 2 n 4. int i=2; /*5*/ 5. printf(“%d”,f(i)); 2 i 6. system(“pause”); 7. } 4 8. int f(int n)//递归函数:求n! 递归函数: 递归函数 9. { 10. if(n==0) 11. return 1; f(1)返 返 12. 回值1 else 回值 13. return n*f(n-1); f(2)返 返 回值2 回值 14. }