八、递归ppt
合集下载
递归的概念递归过程与递归工作栈递归与回溯广义表ppt课件62页PPT

递归的概念 递归过程与递归工作栈 递归与回溯 广义表
递归的概念
递归的定义 若一个对象部分地包含它 自己, 或用它自己给自己定义, 则称这 个对象是递归的;若一个过程直接地或 间接地调用自己, 则称这个过程是递归 的过程。
以下三种情况常常用到递归方法。 定义是递归的 数据结构是递归的 问题的解法是递归的
do {
while ( n > 1 ) { w->n = n; w->tag = 1; S.push ( w ); n--;
} //向左递归到底, 边走边进栈 sum = sum + n; //执行求和
while ( !S.IsEmpty( ) ) { w = S.getTop( ); S.Pop( ); if ( w->tag == 1 ) { //改为向右递归 w->tag = 2; S.push ( w ); n = w->n – 2; //F(n)右侧为F(n-2) break; }
Fib(1) Fib(0)
2 1 2 2
3 1 3 1 3 1 3 2
4 1 4 1 4 1 4 1 4 1 4 2
n=1
n=0
n=1
sum=0+1 n=2-2 sum=1+0 n=3-2 sum=1+1 n=4-2
Fib(4)
Fib(3)
Fib(2) Fib(1)
递归调用
n! (n-1)! (n-2)!
1! 0!=1
返回次序
主程序第一次调用递归过程为外部调用;
递归过程每次递归调用自己为内部调用。
它们返回调用它的过程的地址不同。
递归的概念
递归的定义 若一个对象部分地包含它 自己, 或用它自己给自己定义, 则称这 个对象是递归的;若一个过程直接地或 间接地调用自己, 则称这个过程是递归 的过程。
以下三种情况常常用到递归方法。 定义是递归的 数据结构是递归的 问题的解法是递归的
do {
while ( n > 1 ) { w->n = n; w->tag = 1; S.push ( w ); n--;
} //向左递归到底, 边走边进栈 sum = sum + n; //执行求和
while ( !S.IsEmpty( ) ) { w = S.getTop( ); S.Pop( ); if ( w->tag == 1 ) { //改为向右递归 w->tag = 2; S.push ( w ); n = w->n – 2; //F(n)右侧为F(n-2) break; }
Fib(1) Fib(0)
2 1 2 2
3 1 3 1 3 1 3 2
4 1 4 1 4 1 4 1 4 1 4 2
n=1
n=0
n=1
sum=0+1 n=2-2 sum=1+0 n=3-2 sum=1+1 n=4-2
Fib(4)
Fib(3)
Fib(2) Fib(1)
递归调用
n! (n-1)! (n-2)!
1! 0!=1
返回次序
主程序第一次调用递归过程为外部调用;
递归过程每次递归调用自己为内部调用。
它们返回调用它的过程的地址不同。
8递归数列的通项(3)

第八讲 递归数列的通项(3) ——几种特殊的循环数列 设数列 {bn } 是一个通项公式已知的数列(或为等差数列, 或为等比数列), r是不等于1的非零常数。 数列{an } 的递推公式为 an +1 = ran + bn 初始值a1已知 这个数列可以利用 {bn } 的通项公式及
初 等 数 学 专 题 研 究
这是一个三阶循环公式 将得到一个次数较高的特征方程,求解计算量大。 下面针对 {bn } 的几种特殊情形给出求数列 {a } n 通项公式的一般方法。
初 等 数 学 专 题 研 究
情形一: {bn } 为常数数列 bn = b 即 an +1 = ran + b 这时,我们设想,如果b能够拆解成两个部分, 使 an+1 = ran + b 能改写成: 的形式。那么数列 {a n + x } 就成为公比为r的等比数列。 问题是这样的待定数x是否存在? 将 an +1 + x = r (an + x ) 还原成 an +1 = ran + x ( r 1) 的形式, 与 an +1 = ran + b 比较, 由于
与
an+1 = ran + bn + c 比较,
由于
r ≠1
所以方程组
初 等 数 学 专 题 研 究
( r 1) x = b x + ( r 1) y = c
有解,即前面的设想成立。
例2:求数列:an+1 = 4an + 5n, a1 = 1 的通项公式。 解:设 an +1 = 4an + 5n 可以改写成
bn = an +1 ran , bn+1 = an + 2 ran +1
初 等 数 学 专 题 研 究
这是一个三阶循环公式 将得到一个次数较高的特征方程,求解计算量大。 下面针对 {bn } 的几种特殊情形给出求数列 {a } n 通项公式的一般方法。
初 等 数 学 专 题 研 究
情形一: {bn } 为常数数列 bn = b 即 an +1 = ran + b 这时,我们设想,如果b能够拆解成两个部分, 使 an+1 = ran + b 能改写成: 的形式。那么数列 {a n + x } 就成为公比为r的等比数列。 问题是这样的待定数x是否存在? 将 an +1 + x = r (an + x ) 还原成 an +1 = ran + x ( r 1) 的形式, 与 an +1 = ran + b 比较, 由于
与
an+1 = ran + bn + c 比较,
由于
r ≠1
所以方程组
初 等 数 学 专 题 研 究
( r 1) x = b x + ( r 1) y = c
有解,即前面的设想成立。
例2:求数列:an+1 = 4an + 5n, a1 = 1 的通项公式。 解:设 an +1 = 4an + 5n 可以改写成
bn = an +1 ran , bn+1 = an + 2 ran +1
C++函数、递推、递归ppt课件

i = 7 s1 = 2 * (s2 + 1) ; s2 = s1 ;
// S(7) = 2 * (S(8) + 1) // s2 = s1 = S(7)
i = 6 s1 = 2 * (s2 + 1) ; s2 = s1 ;
// S(6) = 2 * (S(7) + 1) // s2 = s1 = S(6)
看一个简单的例子:
1 4
第九讲——函数、递推、递归
递归
有 5 个人坐在一起,问第 5 个人多少岁? 他说比第 4 个人 大两岁。问第 4 个人岁数,他说比第 3 个人大两岁。问第 3 个人,又说比第 2 个人大两岁。问第 2 个人,说比第 1 个人 大两岁。最后问第 1 个人,他说是 10 岁。请问第 5 个人多 大?
3
第九讲——函数、递推、递归
解题思路:
假设用 S(i) 表示第 i 天没吃之前的桃子数目;
则
S(1) 即为第 1 天所摘的桃子数; S(2) = S(1) * 1/2 – 1 第 2 天没吃之前的桃子数
S(3) = S(2) * 1/2 - 1 第 3 天没吃之前的桃子数
…
…
S(9) = S(8) * 1/2 - 1 第 9 天没吃之前的桃子数
= age(2) + 2 + 2 + 2 // c = age(2) + 2
= age(1) + 2 + 2 + 2 + 2;// c = 10;
2 2
计算年龄程序
第九讲——函数、递推、递归
2 3
第九讲——函数、递推、递归
递归算例(2)
用递归方法计算 n! 算法思路:
八皇后问题详细的解法ppt课件

回溯法指导思想——走不通,就掉头。
10
火灾袭来时要迅速疏散逃生,不可蜂 拥而出 或留恋 财物, 要当机 立断, 披上浸 湿的衣 服或裹 上湿毛 毯、湿 被褥勇 敢地冲 出去
1 回溯法
求问题所有解:要回溯到根,且根结点的所有子树都 已被搜索遍才结束。
求任一解:只要搜索到问题的一个解就可结束。
11
2 回溯法应用-算法说明
八皇后问题中的核心代码: 遍历过程函数; check函数。
解决此类问题的核心内容: 解空间树的搜索算法; 估值/判断函数:判断哪些状态适合继续扩展,或者作 为答案状态。
18
火灾袭来时要迅速疏散逃生,不可蜂 拥而出 或留恋 财物, 要当机 立断, 披上浸 湿的衣 服或裹 上湿毛 毯、湿 被褥勇 敢地冲 出去
else
for(i=1;i<=8;i++)
print(a[i]);
}
9
}
火灾袭来时要迅速疏散逃生,不可蜂 拥而出 或留恋 财物, 要当机 立断, 披上浸 湿的衣 服或裹 上湿毛 毯、湿 被褥勇 敢地冲 出去
1 回溯法
有“通用的解题法”之称。 回溯法的基本做法是搜索,或是一种组织得井井有条
的,能避免不必要搜索的穷举式搜索法。这种方法适 用于解一些组合数相当大的问题。 回溯法在问题的解空间树中,按深度优先策略,从根 结点出发搜索解空间树。算法搜索至解空间树的任意 一点时,先判断该结点是否包含问题的解。如果肯定 不包含,则跳过对该结点为根的子树的搜索,逐层向 其祖先结点回溯;否则,进入该子树,继续按深度优 先策略搜索。
2 回溯法应用-n皇后问题
介绍过的方法: c递归回溯算法; d非递归回溯算法; 策略:能进则进,不能进则换,不能换则退。
10
火灾袭来时要迅速疏散逃生,不可蜂 拥而出 或留恋 财物, 要当机 立断, 披上浸 湿的衣 服或裹 上湿毛 毯、湿 被褥勇 敢地冲 出去
1 回溯法
求问题所有解:要回溯到根,且根结点的所有子树都 已被搜索遍才结束。
求任一解:只要搜索到问题的一个解就可结束。
11
2 回溯法应用-算法说明
八皇后问题中的核心代码: 遍历过程函数; check函数。
解决此类问题的核心内容: 解空间树的搜索算法; 估值/判断函数:判断哪些状态适合继续扩展,或者作 为答案状态。
18
火灾袭来时要迅速疏散逃生,不可蜂 拥而出 或留恋 财物, 要当机 立断, 披上浸 湿的衣 服或裹 上湿毛 毯、湿 被褥勇 敢地冲 出去
else
for(i=1;i<=8;i++)
print(a[i]);
}
9
}
火灾袭来时要迅速疏散逃生,不可蜂 拥而出 或留恋 财物, 要当机 立断, 披上浸 湿的衣 服或裹 上湿毛 毯、湿 被褥勇 敢地冲 出去
1 回溯法
有“通用的解题法”之称。 回溯法的基本做法是搜索,或是一种组织得井井有条
的,能避免不必要搜索的穷举式搜索法。这种方法适 用于解一些组合数相当大的问题。 回溯法在问题的解空间树中,按深度优先策略,从根 结点出发搜索解空间树。算法搜索至解空间树的任意 一点时,先判断该结点是否包含问题的解。如果肯定 不包含,则跳过对该结点为根的子树的搜索,逐层向 其祖先结点回溯;否则,进入该子树,继续按深度优 先策略搜索。
2 回溯法应用-n皇后问题
介绍过的方法: c递归回溯算法; d非递归回溯算法; 策略:能进则进,不能进则换,不能换则退。
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个元素之间寻找最大和
递归算法课件

写成函数形式,则为:
当n 0时 1 f ( n) n * f (n 1) 当n 0时
这种函数定义的方法是用阶乘函数自己本身定义了 阶乘函数,称上式为阶乘函数的递推定义式。
数学归纳法表明,如果我们知道某个论点对最小的情 形成立,并且可以证明一个情形暗示着另一个情形,那么我 们就知道该论点对所有情形都成立。 数学有时是按递归方式定义的。 例1:假设S(n)是前n个整数的和,那么S(1)= 1,并且 我们可以将S(n)写成S(n)= S(n-1)+ n。 根据递归公式,我们可以得到对应的递归函数: int S(int n) { if (n == 1) return 1; else return S(n-1) + n; } 函数由递归公式得到,应该是好理解的,要想求出S (n),得先求出S(n-1),递归终止的条件(递归出口)是(n == 1)。
↑
low 第二次: 下标 元素值 0 1 1 3 2 4
↑
mid 3 5 4 17 5 18 6 31
↑
high 7 33
↑
low 第三次: 下标 元素值 0 1 1 3 2 4 3 5 4 17
↑
mid 5 18 6 31
↑
high 7 33
↑
low high mid
• Public static void main(String args[]) •{ • int[] shus={1,3,4,5,17,18,31,33};
求Fib(5)的递归计算过程如图所示。
Fib(5) Fib(4) Fib(3) Fib(2) Fib(1) Fib(2) Fib(3) Fib(2) Fib(1) Fib(0)
Fib(1) Fib(0) Fib(1)
当n 0时 1 f ( n) n * f (n 1) 当n 0时
这种函数定义的方法是用阶乘函数自己本身定义了 阶乘函数,称上式为阶乘函数的递推定义式。
数学归纳法表明,如果我们知道某个论点对最小的情 形成立,并且可以证明一个情形暗示着另一个情形,那么我 们就知道该论点对所有情形都成立。 数学有时是按递归方式定义的。 例1:假设S(n)是前n个整数的和,那么S(1)= 1,并且 我们可以将S(n)写成S(n)= S(n-1)+ n。 根据递归公式,我们可以得到对应的递归函数: int S(int n) { if (n == 1) return 1; else return S(n-1) + n; } 函数由递归公式得到,应该是好理解的,要想求出S (n),得先求出S(n-1),递归终止的条件(递归出口)是(n == 1)。
↑
low 第二次: 下标 元素值 0 1 1 3 2 4
↑
mid 3 5 4 17 5 18 6 31
↑
high 7 33
↑
low 第三次: 下标 元素值 0 1 1 3 2 4 3 5 4 17
↑
mid 5 18 6 31
↑
high 7 33
↑
low high mid
• Public static void main(String args[]) •{ • int[] shus={1,3,4,5,17,18,31,33};
求Fib(5)的递归计算过程如图所示。
Fib(5) Fib(4) Fib(3) Fib(2) Fib(1) Fib(2) Fib(3) Fib(2) Fib(1) Fib(0)
Fib(1) Fib(0) Fib(1)
高中信息技术课件:递归算法 (共19张PPT)

(3)编写程序 窗ຫໍສະໝຸດ 中开设一个文本框Text1用于填 人月数N,设置命令框Commandl,点击 它即执行程序求出第N月的兔子数。然后用 文本框Text2输出答案。
根据递推式可以写出递归程序如下:
Function Fib(ByVal N As Integer) As Long If N < 3 Then Fib = 1 Else Fib = Fib(N - 1) + Fib(N - 2) End Function Private Sub Command1_Click() N = Val(Text1.Text) Text2.Text = "第" & N & "月的兔子数目是:" & Fib(N) End Sub
递 归 算 法
什么是递归算法?
递归算法:是一种直接或者间接地调 用自身的算法。在计算机编写程序中,递 归算法对解决一大类问题是十分有效的, 它往往使算法的描述简洁而且易于理解。
斐波那契的兔子问题
某人有一对兔子饲养在围墙中,如 果它们每个月生一对兔子,且新生的兔子 在第二个月后也是每个月生一对兔子,问 一年后围墙中共有多少对兔子。
算法:
① ② ③ ④ ⑤ ⑥ 输入计算兔子的月份数:n If n < 3 Then c = 1 Else a = 1: b = 1 i=3 c = a + b:a = b:b = c i=i+1,如果i≤n则返回④ 结束
Private Sub Command1_Click() n = Val(Text1.Text) If n < 3 Then c = 1 Else a = 1: b = 1 For i = 3 To n c=a+b a=b b=c Next i Text2.Text = "第" & n & "月的兔子数目是:" &c End Sub
八皇后问题详细的解法PPT课件

枚举得有个顺序,否则 轻则有漏的、重复的; 重则无法循环表示。
6
1.按什么顺序去查找所有的解 a.盲目的枚举算法
void main() {
int x[100]; for (x[1]=1;x[1]<=10;x[1]++)
for (x[2]=1;x[2]<=10;x[2]++) for (x[3]=1;x[3]<=10;x[3]++) for (x[4]=1;x[4]<=10;x[4]++) for (x[5]=1;x[5]<=10;x[5]++) for (x[6]=1;x[6]<=10;x[6]++) for (x[7]=1;x[7]<=10;x[7]++) for (x[8]=1;x[8]<=10;x[8]++) if (check(x)==0) { printf(x); }
}
10
1 回溯法
有“通用的解题法”之称。 回溯法的基本做法是搜索,或是一种组织得井井有条
的,能避免不必要搜索的穷举式搜索法。这种方法适 用于解一些组合数相当大的问题。 回溯法在问题的解空间树中,按深度优先策略,从根 结点出发搜索解空间树。算法搜索至解空间树的任意 一点时,先判断该结点是否包含问题的解。如果肯定 不包含,则跳过对该结点为根的子树的搜索,逐层向 其祖先结点回溯;否则,进入该子树,继续按深度优 先策略搜索。
按什么顺序去搜? 目标是没有漏网之鱼,尽量速度快。
5
2 【问题设计】盲目的枚举算法
a 盲目的枚举算法 通过8重循环模拟搜索空间中的88个状态; 按枚举思想,以DFS的方式,从第1个皇后在第1列开始 搜索,枚举出所有的“解状态”:
递归及递归算法分析课件

A(1,1)=2故A(n,1)=2*n ❖ M=2时,A(n,2)=A(A(n-1,2),1)=2A(n-1,2),和
A(1,2)=A(A(0,2),1)=A(1,1)=2,故A(n,2)= 2^n 。
2 222
❖ M=3时,类似的可以推出
n
❖ M=4时,A(n,4)的增长速度非常快,以至于没有适当的数 学式子来表示这一函数。
❖
move(a,b);
❖
hanoi(n-1, c, b, a);
❖
}
❖}
❖ T(n)=2T(n-1)+O(1) n≥1
T(n)=2n-1
0
n=0
4
27
简单递归式的求解
1.T(n)=T(n-1)+c1 n>1
c2
n=1
2. T(n)=2T(n/2)+c1 n ≥2
c2
n<2
3. T(n)=2T(n/2)+Θ(n) n ≥2
O(1)
n<2
28
T( n/2 ) + T( n/2 ) + 1
例1 T(n) =
0
(n = 1)
解 :T(n)=2T(n/2)+1
=22T(n/22)+2+1
=23T(n/23)+22+2+1
令2r=n =2rT(1)+2r-1+。。。+2+1
=(1-2r)/(1-2)=n-1
∴ T( n ) = n - 1
25
递归算法的时间复杂度分析
❖ 递归函数求解
简单递归式求解 master method 递推方程的特征方程求解
A(1,2)=A(A(0,2),1)=A(1,1)=2,故A(n,2)= 2^n 。
2 222
❖ M=3时,类似的可以推出
n
❖ M=4时,A(n,4)的增长速度非常快,以至于没有适当的数 学式子来表示这一函数。
❖
move(a,b);
❖
hanoi(n-1, c, b, a);
❖
}
❖}
❖ T(n)=2T(n-1)+O(1) n≥1
T(n)=2n-1
0
n=0
4
27
简单递归式的求解
1.T(n)=T(n-1)+c1 n>1
c2
n=1
2. T(n)=2T(n/2)+c1 n ≥2
c2
n<2
3. T(n)=2T(n/2)+Θ(n) n ≥2
O(1)
n<2
28
T( n/2 ) + T( n/2 ) + 1
例1 T(n) =
0
(n = 1)
解 :T(n)=2T(n/2)+1
=22T(n/22)+2+1
=23T(n/23)+22+2+1
令2r=n =2rT(1)+2r-1+。。。+2+1
=(1-2r)/(1-2)=n-1
∴ T( n ) = n - 1
25
递归算法的时间复杂度分析
❖ 递归函数求解
简单递归式求解 master method 递推方程的特征方程求解
第8课 变量过程与递归过程.ppt

带多个变量的过程
修改 “NBX” 的过程,分别调用它们画出不同边长、不同边数的正多边 形。
1 在命令窗口输入: EDIT NBX,打开 NBX的编辑窗口, 用“:D”表示图形 的边长,按图8-3所 示修改过程。
图8-3
2 按F2键,定义过程,并保存过程。
3 在命令窗口,分别调用 “NBX” 的过程: NBX 4 30 NBX 6 65
转动的风车
经过定义的过程, 既可以当作命令使 用,也可以在其他 的过程中被调用。 如图8-4所示的过 程“FY”中调用了 “NBX”过程。我 们称被调用的 “NBX”为子过程, 调用子过程的“FY” 为主过程。
调用“NBX”过 程
调用“FY”过程
图8-4
Logo系统中,一个过程可以调用另一个过程,也可以进行自我调用,这种 自己调用自己的过程被称为递归调用。
第8课变量过程与递归过程
学
认识并学会编写带变量的过程及递归过程
习
了解过程中的条件语句
目
标
学会将绘图窗口以图片的形式保存
带一个变量的过程
图8-1
如图8-1所示,在正三角形、 正五边形等的过程中,使 用的命令结构是相同的, 不同的是图形的边数。我 们可以将过程体内的图形 边数设为变量,调用过程 时再根据需要给出图形的 具体边数。
命令 停止命令 条件语句
格式 STOP IF条件表达式 THEN命令
功能
在过程中,当执行到这条命令时,停止这个过程的执行。
当条件表达式成立时,执行THEN后面的命令;当条件表达式 不成立时,直接执行下一条命令。
编写如图8-8所示的三角螺旋线的过程,并定义后调用。如果初始边长 A为30,所画图形如图8-9所示。
递归第1课时递归的概念与特征课件浙教版(2019)高中信息技术选修1(25张PPT)

利用递归解决问题
Use recursion to solve problems
#02
问 题
problem
在迭代中,斐波那契数列指的是这样一个数列: 1,1,2,3,5,8,13,21,34,...即从第3项开始,每一项都是前面两项的和。请根据同学们斐波那契数列的定义,用递归算法去求解斐波那契数列的第n项,编写计算斐波那契数列的程序, 并求出斐波那契数列第45项的结果,自定义函数名为fib。
a→c
move(n-1, b, a, c)
【程序实现】
def move(n,a,b,c): global s if n==1: s+=1 print(a,"->",c,s) else: move(n-1,a,c,b) move(1,a,b,c) move(n-1,b,a,c) returnn=int(input("请输入盘子数:"))s=0move(n,"A","B","C")
楼梯上有8级台阶,从下开始往上走,每次可以走一步或者两步,自定义函数fg可以计算走完n级台阶有多少种走法。实现对应功能的Python程序如下:def fg(n): if n==1: return 1 elif n==2: return 2 else: return fg(n-1)+fg(n-2)Print(‘走完8级台阶的方法共有’,fg(8),‘种’)则走完这8级台阶的走法有( )A.34种 B.35种 C.36种 D.37种
分析问题
递归公式与递归条件:根据定义可知:ib() = ib(−) + ib(−) ≥, ∈ 当 = 或者 = 的时候 ib() 为 ,此时直接返回结果就可以。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
递归函数的设计 Hanoi塔问题 结束条件:只有一块盘子,将这一盘子直接送到柱C 递归过程:用C柱过渡,将A柱上的盘子送到柱B 直接把A柱上最后一个盘子移到C 将A柱为过渡, 将B柱上(n-1)个盘子移到C void Honoi (int t, 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); } }
递归的定义
若一个对象部分地包含它自己,或用它自己给自己下定义,称这 个对象是递归的;若一个过程直接地或间接地调用自己,则称这 个过程是递归的过程。 long Fractorial(long n) { if (n = = 0) return 1; else return n﹡fractorial(n-1); } 用递归的情况 ⑴定义是递归的; ⑵数据结构是递归的; 如:①一个结点,其指针域为NULL,是一个单链表; ②一个结点,其指针域指向一个单链表,仍是一个单链表。 ⑶问题的解法是递归的。
3、递归过程与递归工作栈 下图反映了阶乘函数计算函数调用过程 4! = 4 ×3! 参数 0 = 4 ×(3 ×2!) = 4 ×(3 ×(2 ×1!)) 参数 = 4 ×(3 ×(2×(1×0!))) 1 = 4 ×(3 ×(2×(1×1))) 参数 2 = 4 ×(3 ×(2×1)) = 4 ×(3 ×2) 参数 3 = 4 ×6 参数 = 24
4
计算 0! = 1
返回 1
计算 返回 1×fractorial(0) 1 计算 返回 2×fractorial(1) 2
计算 返回 3×fractorial(2) 6
计算 返回 4×fractorial(3) 24
主程序 main
4、例 ⑴折半查找 终止条件:查找成功或子表成为空表; 递归步骤:按中间值与关键字大小确定在下子表或上子表中继续 查找。 template<class T> int BinSearch(T A[ ], int low, int high, T key) { int midl; T midvalue; if (low>high) return (-1); else { mid = (low+high)/2; midvalue = A[mid];
八、递归
1、递归的概念 2、递归函数的设计 3、递归过程与递归工作栈个正整数的阶乘通常用以下公式进行定义: n! = n×(n-1)×· · · ×1, 这种技法作为阶乘函数不是很严密。 正规的阶乘定义应为 1 if n = 0 n! = n ×(n-1)! If n >0 4! = 4 ×3! = 4 ×(3 ×2!) = 4 ×(3 ×(2 ×1!)) = 4 ×(3 ×(2×(1×0!))) = 4 ×(3 ×(2×(1×1))) = 4 ×(3 ×(2×1)) = 4 ×(3 ×2) 利用前一次由较小 = 4 ×6 值计算出的结果。 = 24
作
书面作业 10.6 10.11 上机题 10.1 10.2 10.9
业
Fibonacci数列 Fibonacci 数列的定义 1 若n = 1或2 F(n) = F(n –1)+F(n – 2) 若n>2 终止条件:F(1) = F(2)=1 递归步骤: F(n) = F(n –1)+F(n – 2) long Fib(int n) { if (n = =1‖n = =2) return 1 else return Fib(n-1)+Fib(n – 2) }
例(折半查找)
// 终止条件:找到key if (key = = midvalue) return mid; // 若key<midvalue, 则查下子表;否则,查上子表 else if (key < midvalue) // return BinSearch(A, low, mid – 1, key); else return BinSearch ( A, mid+1, high, key); } }
Fib(6)
Fib(5)
Fib(4)
Fib(4)
Fib(3)
Fib(3)
Fib(2)
Fib(3)
Fib(2)
Fib(2)
Fib(1)
Fib(2)
Fib(1)
Fib(2)
Fib(1)
迭代法计算Fibonacci数列
Fibonacci数列的迭代计算 long FibIter(int n) { long twoback =1, oneback = 1, current; int i; // FibIter(1) = FibIter(2) = 1 if (n = =1‖n = =2) return 1; // current = twoback+oneback, n>=3 else for (i =3; i <=n; i + +) { current = twoback + oneback; twoback = oneback; oneback = current; } }
2、递归函数的设计
每一个递归过程由两部分组成: ⑴一个最小的基础情况,它不需用递归来处理; ⑵一个通用的方法(又称递归步骤),它根据先前某次值求当前值, 这一步骤应该导致过程的终止。 使用 if– else 语句,if 语句块判断递归结束的条件,else语句块处 理递归的情况。 幂函数计算 xn = 1 n=0 x﹡x(n-1) n >0 float Fractorial(float x,int n) { if (n = = 0) return 1 else return x ﹡Fractorial(x,n-1) }
5、递归过程的非递归化 用单纯的循环方式非递归化 阶乘的非递归算法 long Factorial (long n) { int prod = 1, i; if (n > 0) for (i = 1; i< = n; i+ +) prod*=i; return prod; }
递归过程的非递归化
用迭代法非递归化