第五章、递归
第5章-递归(高级程序设计)
f(n)=
将n-1个盘从一针移到另一针上 n>1
例 Hanoi问题
A
B
void move(char getone, char putone) { printf("%c--->%c\n",getone,putone); } void hanoi(int n,char one,char two,char three) { if(n==1) move(one,three); else C { hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); } } main() { int m; printf("Input the number of disks:"); scanf("%d",&m); printf("The steps to moving %3d disks:\n",m); hanoi(m,'A','B','C'); }
6.2递归算法及其执行过程
(1)用于某些概念的定义: 阶乘: if ( n>0 ) n ! = n ( n-1 ) ! if ( n=0 ) n ! = 1 单链表结点:
struct node{ datatype data struct node * Link;
} 二叉树:二叉树是数据元素的有穷集合,它或者为空集 (空二叉树),或者由一个根元素和其下的两棵互不相交
6.4 递归过程与运行时栈
为了保证递归调用的正确性,需要保存调用点的现场(返回地 址、局部变量、被调用函数的参数等),以便正确地返回,并且按 先进后出的原则来管理这些信息。在高级语言(编译程序)中,是 通过利用“递归工作栈”来实现递归调用的。 f(n) f(n-1) f(n-2) f(1) f(0)
第5章递归第1讲-什么是递归
数据结构课件第5章递归
return fact; }
递归调用执行情况如下:
int fact (int w) {1if ( w==0) 2 fact= 1; 3else 4fact=w* fact( w-1); }
递归思路
实际上, 递归思路是把一个不能或不好直接求解 的“大问题”转化成一个或几个“小问题”来解决, 再把这些“小问题”进一步分解成更小的“小问题” 来解决,如此分解,直至每个“小问题”都可以直接解 决(此时分解到递归出口)。
但递归分解不是随意的分解,递归分解要保证“大 问题”与“小问题”相似,即求解过程与环境都相似。 并且有一个分解的终点。从而使问题可解。
假 设 f(A,i-1) 已 求 出 , 则 f(A,i)=MIN(f(A,i1),A[i]),其中MIN()为求两个值较小值函数。因 此得到如下递归模型:
A[0] 当i=0时 f(A,i)=
MIN(f(A,i-1),A[i]) 其他情况
由此得到如下递归求解算法:
float f(float A[],int i) { float m;
n!
n
1, (n 1)!,
当n 0时 当n 1时
该问题的算法为: int Fact ( int n )
{ int m; if (n= =0) return(1); else { m=n*Fact(n-1); return(m); } }
例如: 试编一个递归函数,求第n项Fibonacci级数的
} } // delete
5.3 递归算法到非递归算法的转换
递归算法有两个基本特性:一是递 归算法是一种分而治之的、把复杂问 题分解为简单问题的求解问题方法,对 求解某些复杂问题,递归算法分析问题 的方法是十分有效的;二是递归算法 的时间/空间效率通常比较差。
《C语言程序设计教程》第三版课后习题参考答案
《C语言程序设计教程》第三版课后习题参考答案C语言程序设计教程第三版课后习题参考答案第一章:C语言概述1.1 C语言的特点答案:C语言是一种通用的、面向过程的程序设计语言,具有高效、简洁、灵活等特点。
它提供了丰富的程序设计元素和功能,适用于各种不同的应用领域。
1.2 C语言程序的基本结构答案:C语言程序由预处理指令、函数声明、函数定义、变量声明和语句组成。
其中,预处理指令用来引入头文件或定义宏,函数声明用来声明函数的名称和参数,函数定义用来实现函数的功能,变量声明用来声明变量的类型和名称,语句用来表达具体的计算过程。
1.3 C语言的数据类型答案:C语言提供了多种数据类型,包括基本类型(整型、浮点型、字符型等)和派生类型(数组、指针、结构体等)。
每种数据类型在内存中占据一定的存储空间,并具有特定的取值范围和操作规则。
1.4 C语言的运算符和表达式答案:C语言支持各种运算符和表达式,例如算术运算符(+、-、*、/等)、关系运算符(>、<、==等)、逻辑运算符(&&、||、!等)等。
通过运算符和表达式可以进行各种数值计算和逻辑判断。
第二章:基本数据类型与运算2.1 整型数据类型答案:C语言提供了不同长度的整型数据类型,包括有符号整型(int、long等)和无符号整型(unsigned int、unsigned long等)。
整型数据类型可以表示整数值,并具有不同的取值范围。
2.2 浮点型数据类型答案:C语言提供了浮点型数据类型(float、double等),用来表示带小数部分的实数值。
浮点型数据可以表示较大或较小的数值,并具有一定的精度。
2.3 字符型数据类型答案:C语言提供了字符型数据类型(char),用来表示单个字符。
字符型数据可以用于表示各种字符(包括字母、数字、符号等)。
2.4 布尔型数据类型答案:C语言不直接支持布尔型数据类型,但可以使用整型数据类型来表示布尔值(0表示假、非零表示真)。
python课件第五章Python的函数:函数的递归及应用
教学内容
5.5 函数的递归
5.7 内置函数
教学要求
掌握:函数的嵌套与递归。 熟悉:函数的概念、函数化编程的思想。 了解:内置函数的使用。
5.5 函数的递归
函数定义中调用函数自身的方式形成递归。
例5-4 求第n项的阶乘
阶乘一般定义:n!=n(n-1)(n-2)……(1)
2022/2/3
17
5.7 Python内置函数
2022/2/3
18
5.7 Python内置函数
2022/2/3
19
5.7 Python内置函数
2022/2/3
20
小结
掌握:函数的定义和使用;函数的参数和 函数的返回值;函数的嵌套。
熟悉:函数的递归。 了解:内置函数的使用。
课堂小测
单选题 1分
n!=
n(n-1)! (n>0)
2022/2/3
5
5.5 函数的递归
例5-4 求第n项的阶乘
2022/2/3
6
ห้องสมุดไป่ตู้
5.5 函数的递归
执 行 过 程
2022/2/3
7
多选题 1分
下列是递归程序特点的是()。
A 书写简单 B 一定要有基例 C 执行效率高 D 思路简单,但不宜理解
提交
5.5 函数的递归
例5-5 科赫曲线的绘制
2022/2/3
9
5.5 函数的递归
例5-5 科赫曲线的绘制——实验七(见实验课件)
2022/2/3
10
课后思考:汉诺塔问题
问题IPO 输入:汉诺塔的层数 处理:实现一个汉诺塔圆盘的移动,采用递归实现将所有圆盘从A移 动到C。 输出:整个移动流程
递归小总结
递归小总结什么是递归?递归是一种程序设计技巧,在一个函数中调用自身来解决问题。
换句话说,递归是通过把一个问题分解成更小的子问题来解决复杂问题的方法。
递归的原理递归算法的核心思想是将一个大问题分解成一个或多个与原问题类似但规模更小的子问题。
递归函数通过调用自身来解决这些子问题,直到子问题变得足够简单,可以直接求解。
递归函数会一层一层地调用自身,直到达到结束条件结束递归。
递归的基本要素递归函数通常需要包含以下几个基本要素:1.基准条件(基础案例):递归函数需要定义在何时结束递归的条件。
当满足基准条件时,递归将不再进行,而是返回一个最终结果。
2.递归调用:递归函数在处理问题时,会将原问题分解成一个或多个较小的子问题。
为了解决这些子问题,递归函数需要调用自身。
3.问题拆解:递归函数需要根据原问题,将其分解成与原问题类似但规模更小的子问题。
4.合并结果:递归函数需要将子问题的结果合并起来,得到原问题的解。
递归的优缺点递归的优点在于它能够清晰地表达问题的解决思路,简化代码的编写。
在某些问题中,使用递归能够使代码更加简洁易懂。
然而,递归也存在一些缺点。
首先,递归函数的调用过程是逐层深入的,这会占用大量的内存,如果递归的层数过多,可能会导致栈溢出。
此外,递归函数的执行效率通常较低,因为每一次递归调用都会增加函数调用的开销。
递归的应用场景递归算法广泛应用于各种领域,特别是数学、计算机科学和算法设计中。
以下是一些常见的递归应用场景:1.阶乘计算:计算一个正整数的阶乘可以使用递归来实现,如factorial(n) = n * factorial(n-1)。
2.斐波那契数列:斐波那契数列是一个递归定义的数列,其中每一项等于前两项的和。
递归函数可以用来计算斐波那契数列的第 n 项。
3.二叉树遍历:对于二叉树的遍历,可以使用递归来实现前序、中序和后序遍历。
4.文件夹遍历:对于文件夹中的文件和子文件夹,可以使用递归来遍历整个文件目录树。
数据结构(C++)--递归
数据结构(C++)..递归数据结构(C++)..递归1.什么是递归递归是指在函数的定义中调用函数本身的情况。
通过递归,可以解决一些问题,特别是那些问题的解决方法和问题的子问题的解决方法相同或相似的情况。
递归的思想是将大问题拆分成小问题,然后通过解决小问题来解决大问题。
递归过程中,函数会不断调用自身,直到达到某个终止条件。
2.递归的基本要素●递归函数的定义:递归函数是指在函数中调用自身的函数。
●终止条件:递归函数必须有一个终止条件,以终止递归过程,避免无限递归。
●递归调用:递归函数在函数体中调用自身。
3.递归的实现递归可以用于解决很多问题,例如计算阶乘、斐波那契数列等。
3.1 计算阶乘```cppint factorial(int n) {if (n == 0 .......●n == 1) {return 1。
}return n factorial(n.1)。
}```在上述代码中,计算阶乘的递归函数`factorial`通过调用自身来实现。
当n为0或1时,递归终止,返回1。
否则,递归调用`factorial(n.1)`来计算(n.1)的阶乘,并将结果乘以n。
3.2 斐波那契数列```cppint fibonacci(int n) {if (n == 0 .......●n == 1) {return n。
}return fibonacci(n.1) + fibonacci(n.2)。
}```在上述代码中,计算斐波那契数列的递归函数`fibonacci`通过调用自身来实现。
当n为0或1时,递归终止,返回n。
否则,递归调用`fibonacci(n.1)`和`fibonacci(n.2)`来计算前两个数的和。
4.递归的优缺点4.1 优点●代码简洁:递归能将问题简化成更小的问题,提高代码的可读性和可维护性。
●解决复杂问题:递归能解决一些复杂的问题,例如树的遍历、图的搜索等。
4.2 缺点●递归调用会占用大量的栈空间,导致内存消耗较大。
递归讲解
复习输入a,b,c,计算m 。
已知m=),,max(),,max(),,max(c b b a c b b a c b a +⨯+ 请把求三个数的最大数max(x,y,z)定义成函数和过程两种方法作此题。
递 归为了描述问题的某一状态,必须用到它的上一状态,而描述上一状态,又必须用到它的上一状态……这种用自已来定义自己的方法,称为递归定义。
例如:定义函数f(n)为:/n*f(n -1) (n>0)f(n)= |\ 1(n=0)则当n>0时,须用f(n-1)来定义f(n),用f(n-1-1)来定义f(n-1)……当n=0时,f(n)=1。
由上例我们可看出,递归定义有两个要素:(1) 递归边界条件。
也就是所描述问题的最简单情况,它本身不再使用递归的定义。
如上例,当n=0时,f(n)=1,不使用f(n-1)来定义。
(2) 递归定义:使问题向边界条件转化的规则。
递归定义必须能使问题越来越简单。
如上例:f(n)由f(n-1)定义,越来越靠近f(0),也即边界条件。
最简单的情况是f(0)=1。
递归算法的效率往往很低, 费时和费内存空间. 但是递归也有其长处, 它能使一个蕴含递归关系且结构复杂的程序简介精炼, 增加可读性. 特别是在难于找到从边界到解的全过程的情况下, 如果把问题推进一步使其结果仍维持原问题的关系, 则采用递归算法编程比较合适.递归按其调用方式分为: 1. 直接递归, 递归过程P 直接自己调用自己; 2. 间接递归, 即P 包含另一过程 D, 而D 又调用P.递归算法适用的一般场合为:1. 数据的定义形式按递归定义.如裴波那契数列的定义: f(n)=f(n-1)+f(n-2); f(0)=1; f(1)=2.对应的递归程序为:Function fib(n : integer) : integer;Beginif n = 0 then fib := 1 { 递归边界 }else if n = 1 then fib := 2else fib := fib(n-2) + fib(n-1) { 递归 }End;这类递归问题可转化为递推算法, 递归边界作为递推的边界条件.2. 数据之间的关系(即数据结构)按递归定义. 如树的遍历, 图的搜索等.3. 问题解法按递归算法实现. 例如回溯法等.从问题的某一种可能出发, 搜索从这种情况出发所能达到的所有可能, 当这一条路走到" 尽头 "的时候, 再倒回出发点, 从另一个可能出发, 继续搜索. 这种不断" 回溯 "寻找解的方法, 称作" 回溯法 ". 例1、给定N (N>=1),用递归的方法计算1+2+3+4+…+(n-1)+n 。
5.5.1 递归算法与递归函数概述_C语言程序设计案例教程(第2版)_[共2页]
145 〖运行结果〗运行这个程序后,将会产生如下所示的结果。
排序所花费的时间主要消耗在比较和交换操作上,因此,可以认为:比较和交换次数较少的排序算法运行效率较高。
很显然,冒泡排序所需交换的次数依赖于原始数据的排列状态。
如果原始数据排列基本有序,交换次数就少;反之交换次数就多。
另外,从程序中还可以看出,比较操作位于两层for 之中,总共需要进行n (n -1)/2次,这里的执行次数与原始数据的排列顺序无关,甚至当所有数据已经按照升序排列好之后,还是需要将剩余的比较操作进行完毕。
一种改进的方法是:当发现所有数据已经排列好时,立即停止循环。
有兴趣的读者可以思考一下:什么状态表示所有数据已经排好序,并对sort( ) 函数进行修改,以提高冒泡排序算法的运行效率。
5.5 递归算法与递归函数对规模大且复杂度高的问题进行分解是降低求解难度、确保程序质量的一种有效方法。
有很多问题经过分解后会发现子问题的基本结构与原问题完全相同,因此,可以采用求解原问题的基本方法来求解各个子问题。
这种解决问题的思路就是递归。
递归是一种常见的解题方法,掌握递归并了解递归的执行过程是充分利用C 语言编写程序的基本前提。
5.5.1 递归算法与递归函数概述下面先看两个实例,以便说明递归算法的概念。
实例1:计算n 的阶乘。
大家都知道,n 阶乘的数学表达形式是n !,其含义为1×2×3×4…×(n -1)×n 。
从这个数学公式中可以发现,n !可以通过在(n -1)!的基础上再乘上一个n 得到,因此,n !又可以采用下面这种定义形式:n != n ×(n -1)! n ≥1 1 n =0这个定义形式表明:n !等于n 与(n -1)!的乘积。
像这样在定义一个概念的时候又用到自身概念的定义形式被称为递归定义,它直接反映了求解n !的基本过程,即将计算n !的过程分解成n 与(n -1)!的乘积;将计算(n -1)!的过程分解成(n -1)与(n -2)!的乘积;依次类推,直到将计算1!分解成1与0!的乘积为止。
2017-递归
例. Hanoi塔的迭代算法,m是原柱上圆盘的个数 算法HI(m) HI1[建立堆栈]
CREATS(S). HI2[堆栈初始化]
S(m,1,2,3). HI3[利用栈实现递归]
WHILE NOT(StackEmpty(S))DO ((n, i, j, k) S. IF n = 1 THEN MOVE(i, k) ELSE(S(n-1, j, i, k). S(1, i, j, k).
IF p = NULL THEN ( PRINT “Can not find the item”. RETURN. )
S2. IF data(p) = item THEN Dealwith(p). // 通过Dealwith函数 // 对该节点进行一定的处理 ELSE Search( next(p), item).
void Hanoi (int n, String A, String B, String C ) { //解决汉诺塔问题的算法
if ( n == 1 ) cout << "move" << A << " to " << C << endl;
else { Hanoi ( n-1, A, C, B ); cout << " move " << A << " to " << C << endl; Hanoi ( n-1, B, A, C ); }
最后一次发生的递归过程必须最先完成。
例. 计算数组 A 中最大最小元素的算法BS 。 算法BS(A ,i ,j . fmax ,fmin) /* 在数组A的第i个元素到第j个元素之间寻找最大和
离散数学第五章递归函数论数论函数和数论谓词
特征函数 Nx N2 x
N2 rs(x,y) N2(x . y) N2((x+1) . y)
二、简单语句的特征函数
语句
特征函数
x=0 x≠0 x=a x≠a x与y互质
N2 x Nx
N2(x .. a) N(x .. a)
N2(dv(x,y) .. 1)
• A(x1,…,xn)为 真时,f(x1,…,xn)=0; • A(x1,…,xn)为 假时,f(x1,…,xn)=1。
则 f(x1,…,xn)是语句A(x1,…,xn)的特征 函数, 记为
ct A(x1,x2,…,xn)。
定理1 (p55) 任何一个语句A 均有唯一的特征函数
证明:
(1) 存在性:对于任何一个语句A,恒可以如上定义一个函数 f(x1,…,xn),此函数必为语句A的特征函数,故 存在性得证。
则, N2 f(x1,…,xn)为语句A 的特征函数。 证明: 当A(x1,…,xn)真时,由于f(x1,…,xn)=0,
所以 N2 f(x1,…,xn)=0;
当A(x1,…,xn)假时,由已知条件知: f(x1,…,xn)0,所以
N2 f(x1,…,xn)=1 由特征函数的定义知:N2 f(x1,…,xn)为语句 A(x1,…,xn)的特征函数。
一、数论谓词和特征函数
定义:数论谓词是指以自然数集为定义域以真假为 值域的谓词。
定义:由数论谓词利用联结词和量词构成的式子称 为数论语句。
数论语句例子 2为质数 8>7且9为平方数 x为质数 x>7且y为平方数
特征函数
定义:设A(x1,x2,…,xn)是一个含有n个变量的语 句,f(x1,x2,…,xn)是一个数论函数,若对 于任何变元组均有:
《数据结构与算法》PPT课堂课件-第5章-递归
(2) if(n==1)
(3) move(x,z);
(4) else{
(5)
hanoi(n-1,x,z,y);
(6)
move(x,z);
(7)
hanoi(n-1,y,x,z);
(8) }
(9) }
A
B
C
2BAC 8 3ABC 0
1BCA6 2BAC 8 3ABC 0
A
B
C
2BAC 8 3 A B C 0 15
O(n)。对比循环结构的Fib2(n)和递归结构的Fib(n)可发现,循环结构
的Fib2(n)算法在计算第n项的斐波那契数列时保存了当前已经计算得到
的第n-1项和第n-2项的斐波那契数列,因此其时间复杂度为O(n);而递
归结构的Fib(n)算法在计算第n项的斐波那契数列时,必须首先计算第n -1项和第n-2项的斐波那契数列,而某次递归计算得出的斐波那契数列, 如Fib(n-1)、Fib(n-2)等无法保存,下一次要用到时还需要重新递归计
{ printf(“参数错!”);
return -1;
}
if(n == 0) return 1;
else {y = Fact(n - 1); /*递归调用*/
return n * y; }
}
5
为说明该递归算法的执行过程,设计主函数如下
void main(void) {
long int fn;
fn = Fact(3); }
(1) {
(2) if(n= =1)
(3) move(x,z);
(4) else{
(5)
hanoi(n-1,x,z,y);
(6)
move(x,z);
数据结构 第5章_递归
2 m=Fibona(2)+Fibona(1); 1 return(m);
(13)
1
(15)
S3
(8) 2
m=Fibona(2)+Fibona(1);
(9)
(10)
1
(14)
return(1)
return(m);
return(1)
return(1)
(4)
return(1)
(5) 1
(6)
(7) 1 Fibona(5)的执行过程
退出
5.3 递归程序到非递归程序的转换
采用递归方式实现问题的算法程序具有结构清 晰、可读性好、易于理解等优点,但递归程序较之 非递归程序无论是空间需求还是时间需求都更高, 因此在希望节省存储空间和追求执行效率的情况下, 人们更希望使用非递归方式实现问题的算法程序; 另外,有些高级程序设计语言没有提供递归的 机制和手段,对于某些具有递归性质的问题(简称 递归问题)无法使用递归方式加以解决,必须使用 非递归方式实现。因此,本小节主要研究递归程序 到非递归程序的转换方法。
退出
例5 采用非递归方式实现求正整数n的阶乘值。 仍使用Fact(n)表示n的阶乘值。要求解Fact(n) 的值,可以考虑i从0开始,依次取1,2,……,一直到n, 分别求Fact(i)的值,且保证求解Fact(i)时总是以前 面已有的求解结果为基础;当i=n 时,Fact(i)的值即 为所求的Fact(n)的值。
退出
排列问题
设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。
设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。 集合X中元素的全排列记为perm(X)。 (ri)perm(X)表示在全排列perm(X)的每一个排列前加 上前缀得到的排列。R的全排列可归纳定义如下:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》第五章
本章主要内容
递归概念 递归过程的计算机实现 递归过程不同实现方法 可利用递归方法实现的
算法 分治法问题举例 回溯法问题举例 广义表
递归概念
递归的概念:
若一个对象部分地包含自己,则称这个对象是递增归的。
递归问题的特点:
该问题能分解为两类子问题: 非终结问题:需进一步递归的子问题。 终结问题:不需进一步递归就可求解的子问题。 终结问题,亦称为递归终止条件。
while(n>1) { w->n=n;
w->tag=1; s.Push(*w); n- -; } sum+=n; while(! s.IsEmpty()) { *w=s.GetTop();
s.Pop(); if(w->tag==1) { w->tag=2; s.Push(*w); n=w->n-2; break; }
mmaaiinn(())
fa2c4t(4) 4* f4a*c6t(3) 3* 3fa*c2t(2) 2* f2a*c1t(1)
【例】用系统工作栈求裴波那契数列:
#include<iostream.h>
long Fib(long n)
{
if ( n<=1) return n;
return Fib( n-1 )+Fib( n-2 );
struct Node
//用户栈结点的类定义
{ long n; int tag;
Node(long m=0,int t=0):n(m),tag(t){ }
//构造函数,用于将整型数转换为Node型
};
void main()
{
long n;
cout<<"Enter number :";
cin>>n;
for(int i=0;i<=n;i++)
⑨
Fib(4)
⑤
⑧
Fib(3)
③
④
Fib(2)
⑥
⑦
Fib(2)
Fib(1)
Fib(1)
Fib(0)
①
②
Fib(1)
Fib(0)
1. 采用系统提供的递归工作栈:
计算机中对子程序的调用(即C/C++中的函数调用)通常是 通过程序中断方式实现的
采用程序中断方式
在调用子程序前,需要保护现场(即保护调用程序的 局部变量值、实在参数值),和保护断点(即返回地址), 在调用子程序后,需要恢复现场和恢复断点。
cout<<"Fibonacci("<<i<<")="<<Fibonacci(i)<<endl;
}
(未完,转下页)
long Fibonacci(long n) //求裴波那契数列函数定义 {
Stack<Node> s(50); //用户定义栈 Node* w=new Node; long sum=0; do{
保护现场和断点、恢复现场和断点都是通过系统提供 栈来实现的。
在调用子程序前,系统自动生成一个包含现场和断点 数据的工作记录,并将工作记录压入系统栈保护起来
在返回调用程序前,系统自动从系统栈中将工作记录 弹出
使用系统提供的栈实现的递归过程,实质上是子程序嵌套 调用的特例,即函数嵌套调用自己。常称作递归算法。
2. 采用用户自定义栈实现递归过程:
递归过程也可通过引入用户自定义的栈模拟系统提供的 栈操作来加以实现。
这种实现不涉及程序的自我调用(即不涉及程序的中断调 用)。也就不涉及断点保护问题。
数据的入栈及出栈操作不是由系统自动完成,而是由用 户通过编码加以实现,通常称为非递归算法。
用户栈中保存的是不同层递归调用树操作产生的中间结 果数据。
非终结问题经过有限次递归,最终可分解为终结问题。
常见使用递归的地方:
定义是递归的: 数据结构是递增归的: 问题是递归的
递归过程的计算机实现
递归过程:
一个过程在进行中又涉及自身,称此过程为递归过程 此处过程有两种含义:广义的和狭义的
广义的递归过程:描述某个事件的进行特性。 狭义的递归过程(递归算法):特指计算机中通过使用系
在上层运算即将转入下层运算前,将上层运算的中间结 果入栈。
在下层运算结束退回上层运算时,将上层运算的中间结 果出栈
使用用户定义栈求裴波那契数列: (黄色为修改部分)
#include<iostream.h>
#include "… …\sequence_stack.h"
long Fibonacci(long n); //求裴波那契数列函数说明
fmffmfafafaaacaccaccttcitti(tn(t(n(2(4(24(13()3))))) fact(1) fact(2)
void main()
段则是共用的
fact(3)
{ cout<< fact(4); }
ffaacctt((44))
main() fact(4)
fact(3)
fact(2) fact(1)
不同层次的局部变量之间可通过实在参数与形式参数进 行数据传递。
#include<iostream.h>
long fact(long n) { if(n<=1)
return 1; else return n*fact(n-1);}
函数递归调用, 各次调用的数据 存放在栈的不同 空间,彼此相互 独立,函数代码
}
void main()
{
long n; cout<<"Enter number :"; cin>>n;
for(int i=0;i<=n;i++)
cout<< "Fib(" << i << ")=" << Fib(i) <<endl;
}
说明:
main()调用Fib(),称作外部调用
Fib()自己调用自己称作内部调用
其特点是:
不同层次的递归调用,调用的是都是同一段代码(即递 归函数体自身)
但函数每递归调用自己一次,都必须在系统栈中重新分 配一个内存空间(即所谓工作记录),以便存放本层使用 的局部变量和实在参数
显然,不同层次的递归调用,它们的局部变量的变量名 虽然相同,但是作为不同的工作记录的组成部份,存放 在系统栈的不同地方(即内存的不同地方),它们之间是 彼此独立的。
统工作栈实现子程序的自我调用。
递归过程的计算机实现,可有三种方法:
利用系统提供的递归工作栈实现 利用用户自定义的栈实现 用叠代方法实现
用递归调用树描述递归过程:来自【例】裴波那契数列的递推公式:
Fib(n)=
n
当n=0或n=1时
Fib(n-1)+Fib(n-2) 当n>=2时
计算n==4时裴波那契数列的递归调用树: