【最新】递归算法PPT 课件教案讲义(获奖作品) 图文
合集下载
递归算法 ppt课件
ppt课件
14
int fib(int n) { if (n==0) return 0; if (n==1) return 1; return (fib(n-1)+fib(n-2)); }
输入 15 输出 fib(15)=610
//满足边界条件,递归返回 //满足边界条件,递归返回 //递归公式,进一步递归
//调用下一层递归
}
int main()
{
int n,k;
cin >> n >> k;
cout << s(n,k);
return 0;
}
ppt课件
19
【例6】数的计数(Noip2001)
【问题描述】
我们要求找出具有下列性质数的个数(包括输入的自然数n)。先输入一 个自然数n(n≤1000),然后对此自然数按照如下方法进行处理:
8
ppt课件
9
假设把第3步,第4步,第7步抽出来就相当于N=2的情况(把上面2片 捆在一起,视为一片):
ppt课件
10
所以可按“N=2”的移动步骤设计:
①如果N=0,则退出,即结束程序;否则继续往下执行;
②用C柱作为协助过渡,将A柱上的(N-1)片移到B柱上,调用过程mov(n-1,
a,b,c);
本题是典型的递归程序设计题。 (1)当N=1 时,只有一个盘子,只需要移动一次:A—>C; (2)当N=2时,则需要移动三次:
A------ 1 ------> B, A ------ 2 ------> C, B ------ 1------> C. (3)如果N=3,则具体移动步骤为:
教科版选修1《递归法》ppt课件
题的运行效率较低。所以一般不提倡用递归算法 设计程序
递归法的归纳2:
递归算法所体现的“重复”一般有三个要求: 一是每次调用在规模上都有所缩小(通常是减半); 二是相邻两次重复之间有紧密的联系,前一次要为
后一次做准备(通常前一次的输出就作为后一次的 输入); 三是在问题的规模极小时必须用直接给出解答而不 再进行递归调用,因而每次递归调用都是有条件 的(以规模未达到直接解答的大小为条件),无条 件递归调用将会成为死循环而不能正常结束。
• 注意:必须要有一个结束递归的条件,不 得无限递归。
分析步骤:
• 1.决定问题规模的参数。 • 2.问题的边界条件及边界值。 • 3.解决问题的通式。
例:计算一个数的阶乘
• 1!=1 • 2!=1*2 • 3!=1*2*3 • 4!=1*2*3*4 • 5!=1*2*3*4*5 • ……. • n!=1*2*3*4*5*….*n
函数是为了实现某种功能而编写的一段相对独立 的程序。
• 标准函数
Abs( ) 、len( )、mid( )、chr( )、asc( )……
• 自定义函数
自定义函数是指我们自己编写的函数。
自定义函数:
• 在VB中,自定义函数形式如下: • [Public|Private] Function <函数名称> ([参数列表]) [As
f(1)=1 f(2)=f(1)*2 f(3)=f(2)*3 f(4)=f(3)*4 f(5)=f(4)*5 …….. f(n)=f(n-1)*n
递归函数求5!
• Public Function s(n As Integer) As Long
• If n = 1 Then
• s =1
• Else
递归法的归纳2:
递归算法所体现的“重复”一般有三个要求: 一是每次调用在规模上都有所缩小(通常是减半); 二是相邻两次重复之间有紧密的联系,前一次要为
后一次做准备(通常前一次的输出就作为后一次的 输入); 三是在问题的规模极小时必须用直接给出解答而不 再进行递归调用,因而每次递归调用都是有条件 的(以规模未达到直接解答的大小为条件),无条 件递归调用将会成为死循环而不能正常结束。
• 注意:必须要有一个结束递归的条件,不 得无限递归。
分析步骤:
• 1.决定问题规模的参数。 • 2.问题的边界条件及边界值。 • 3.解决问题的通式。
例:计算一个数的阶乘
• 1!=1 • 2!=1*2 • 3!=1*2*3 • 4!=1*2*3*4 • 5!=1*2*3*4*5 • ……. • n!=1*2*3*4*5*….*n
函数是为了实现某种功能而编写的一段相对独立 的程序。
• 标准函数
Abs( ) 、len( )、mid( )、chr( )、asc( )……
• 自定义函数
自定义函数是指我们自己编写的函数。
自定义函数:
• 在VB中,自定义函数形式如下: • [Public|Private] Function <函数名称> ([参数列表]) [As
f(1)=1 f(2)=f(1)*2 f(3)=f(2)*3 f(4)=f(3)*4 f(5)=f(4)*5 …….. f(n)=f(n-1)*n
递归函数求5!
• Public Function s(n As Integer) As Long
• If n = 1 Then
• s =1
• Else
递归算法课件
写成函数形式,则为:
当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)
递归与分治策略讲义课件(ppt 65页)
int prev,now,next,j; if (n<=1) return(1);
else {
prev=1; now=1; for(j=2;j<=n;j++) {
next=prev+now; prev=now; now=next; } return(next); } }
具有编译递归程序能力的程 序设计语言有:C、Pascal 、 ALGOL、 PL/A 、 ADA、 QBASIC等,不具有编译递归 程序能力的程序设计语言有: FORTRAN、 COBOL、BASIC、 低级语言。
Hanio(3,A,B,C) Hanio(2,A,C,B)
Move (A,C)
Hanio(2,B,A,C)
结束
Hanio(2,A,C,B)
Hanio(1,A,B,C) Move (A,B)
Hanio(1,C,A,B)
Hanio(1,A,B,C) Move (A,C)
Hanio(1,C,A,B) Move (C,B)
例3 Hanoi塔问题
设x,y,z是3个塔座。开始时,在塔座x上有一叠共n个圆盘,这 些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号 为1,2,…,n,现要求将塔座x上的这一叠圆盘移到塔座z上,并仍 按同样顺序叠置。在移动圆盘时应遵守以下移动规则:
规则1:每次只能移动1个圆盘;
规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上;
(1)运行开始时,首先为递归调用建立一个工作栈,其结 构包括值参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的值参和局部变 量的当前值以及调用后的返回地址压栈;
(3)每次递归调用结束后,将栈顶元素出栈,使相应的值 参和局部变量恢复为调用前的值,然后转向返回地址指定 的位置继续执行。
else {
prev=1; now=1; for(j=2;j<=n;j++) {
next=prev+now; prev=now; now=next; } return(next); } }
具有编译递归程序能力的程 序设计语言有:C、Pascal 、 ALGOL、 PL/A 、 ADA、 QBASIC等,不具有编译递归 程序能力的程序设计语言有: FORTRAN、 COBOL、BASIC、 低级语言。
Hanio(3,A,B,C) Hanio(2,A,C,B)
Move (A,C)
Hanio(2,B,A,C)
结束
Hanio(2,A,C,B)
Hanio(1,A,B,C) Move (A,B)
Hanio(1,C,A,B)
Hanio(1,A,B,C) Move (A,C)
Hanio(1,C,A,B) Move (C,B)
例3 Hanoi塔问题
设x,y,z是3个塔座。开始时,在塔座x上有一叠共n个圆盘,这 些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号 为1,2,…,n,现要求将塔座x上的这一叠圆盘移到塔座z上,并仍 按同样顺序叠置。在移动圆盘时应遵守以下移动规则:
规则1:每次只能移动1个圆盘;
规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上;
(1)运行开始时,首先为递归调用建立一个工作栈,其结 构包括值参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的值参和局部变 量的当前值以及调用后的返回地址压栈;
(3)每次递归调用结束后,将栈顶元素出栈,使相应的值 参和局部变量恢复为调用前的值,然后转向返回地址指定 的位置继续执行。
递归及递归算法分析课件
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 递推方程的特征方程求解
VB递归算法 PPT课件
End Sub
Function f(n as integer)as integer if n<=1 then f=1
Else f=n* f(n-1)
End if End function
观察如下VB程序段:
Function fx(n As Integer) As Long
If n = 1 Then
练习题
➢ 用递归算法求 1~n 个连续自然数的和
Function sum(n As Integer) As Integer If n = 1 Then sum = 1 Else sum = sum(n - 1) + n End If End Function
Private Sub Command1_Click() Dim n As Integer n = Val(Text1.Text) Text2.Text = Str(sum(n)) End Sub
fact = 1 ……
fact (3)=6 返回
fact (2)=2 返回
fact (1)=1 返回
递归算法的实现要点
➢ (1)有明确的结束递归的边界条件(又称终止条件)以及结束 时的边界值,可以通过条件语句(If语句)来实现
➢ (2)函数的描述中包含其本身,即能用递归形式表示,且递 归终止条件的发展。
If n <= 1 Then
fact = 1
Else
fact = n * fact (n - 1)
End If
End Function
Private Sub Command1_Click()
Dim y As Integer y = fact(3) Print y
End Sub
Function f(n as integer)as integer if n<=1 then f=1
Else f=n* f(n-1)
End if End function
观察如下VB程序段:
Function fx(n As Integer) As Long
If n = 1 Then
练习题
➢ 用递归算法求 1~n 个连续自然数的和
Function sum(n As Integer) As Integer If n = 1 Then sum = 1 Else sum = sum(n - 1) + n End If End Function
Private Sub Command1_Click() Dim n As Integer n = Val(Text1.Text) Text2.Text = Str(sum(n)) End Sub
fact = 1 ……
fact (3)=6 返回
fact (2)=2 返回
fact (1)=1 返回
递归算法的实现要点
➢ (1)有明确的结束递归的边界条件(又称终止条件)以及结束 时的边界值,可以通过条件语句(If语句)来实现
➢ (2)函数的描述中包含其本身,即能用递归形式表示,且递 归终止条件的发展。
If n <= 1 Then
fact = 1
Else
fact = n * fact (n - 1)
End If
End Function
Private Sub Command1_Click()
Dim y As Integer y = fact(3) Print y
End Sub
求解递归方程-11省公开课一等奖全国示范课微课金奖PPT课件
第141页4
二、K阶常系数线性非齐次递归方程
f
(n)
a1
f
(n 1) f (i)
a2 bi
f
(nΒιβλιοθήκη 2) ... ak 0ik
f
(n
k)
g(n)
其中,bi为常数,第2项为方程初始条件。
它通解形式为: f (n) f (n) f *(n)
其中,
K1阶)常f 系(n数) 线为性对非应齐齐次次递递归归方方程程形通如解:
前面2种情况下c1,c2,…,ck均为待定系数; 将初始条件代入,建立联立方程,确定各个系数详细值,得到
通解f(n)
例1. 3阶常系数线性齐次递归方程以下
f (n) 6 f (n 1) 11 f (n 2) 6 f (n 3)
f (0) 0
f (1) 2
f (2) 10
解: 特征方程为 x3 - 6x2 + 11x - 6 = 0
求解递归方程
第1页 1
算法复杂性经常描述为递归方程,解递归方程得到算法复 杂性详细表示 • 用特征方程解递归方程 • 用生成函数解递归方程 • 用递推方法解递归方程
第2页 2
用特征方程解递归方程
K阶常系数线性齐次递归方程 K阶常系数线性非齐次递归方程
第3页 3
K阶常系数线性齐次递归方程
f (n) 41 2n 43 5n n2 13 n 103
3 24
28
第212页1
第222页2
g(n) b1nm b2nm1 ... bmn bm1
其中,bi为常数。 此时,特解f*(n)也是nm次多项式,形如:
f * (n) A1nm A2nm1 ... Amn Am1
各个系数Ai待定
二、K阶常系数线性非齐次递归方程
f
(n)
a1
f
(n 1) f (i)
a2 bi
f
(nΒιβλιοθήκη 2) ... ak 0ik
f
(n
k)
g(n)
其中,bi为常数,第2项为方程初始条件。
它通解形式为: f (n) f (n) f *(n)
其中,
K1阶)常f 系(n数) 线为性对非应齐齐次次递递归归方方程程形通如解:
前面2种情况下c1,c2,…,ck均为待定系数; 将初始条件代入,建立联立方程,确定各个系数详细值,得到
通解f(n)
例1. 3阶常系数线性齐次递归方程以下
f (n) 6 f (n 1) 11 f (n 2) 6 f (n 3)
f (0) 0
f (1) 2
f (2) 10
解: 特征方程为 x3 - 6x2 + 11x - 6 = 0
求解递归方程
第1页 1
算法复杂性经常描述为递归方程,解递归方程得到算法复 杂性详细表示 • 用特征方程解递归方程 • 用生成函数解递归方程 • 用递推方法解递归方程
第2页 2
用特征方程解递归方程
K阶常系数线性齐次递归方程 K阶常系数线性非齐次递归方程
第3页 3
K阶常系数线性齐次递归方程
f (n) 41 2n 43 5n n2 13 n 103
3 24
28
第212页1
第222页2
g(n) b1nm b2nm1 ... bmn bm1
其中,bi为常数。 此时,特解f*(n)也是nm次多项式,形如:
f * (n) A1nm A2nm1 ... Amn Am1
各个系数Ai待定
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例6-1 给出按照公式6-3计算阶乘函数的递归算法, 并给出n = 3时递归算法的执行过程。 设计:按照公式6-3计算阶乘函数的递归算法如下:
long int Fact(int n) { int x; long int y; if(n < 0) { printf(“参数错!”); return -1; if(n == 0) return 1; else {y = Fact(n - 1); return n * y; } }
14
void towers(int n, char fromPeg, char toPeg, char auxPeg) { if(n==1) { //递归出口
printf("%s%c%s%c\n", "move disk 1 from peg ", fromPeg, " to peg ", toPeg); return;
5
//n < 0时阶乘无定义
}
//递归调用
设计主函数如下
void main(void)
{
long int fn; fn = Fact(3);
}
主函数用实参n= 3调用了递归算法Fact(3),而 Fact(3)要通过调用Fact(2)、Fact(2)要通过调用Fact(1)、 Fact(1)要通过调用Fact(0)来得出计算结果。Fact(3)的 递归调用过程如图6-2所示。
else printf("x在数组a的下标%d中", bn); }
9
BSearch(a, x, 0,7)的递归调用过程如图6-3所示, 其中,实箭头表示函数调用,虚箭头表示函数的返回值。
图6-3 BSearch(a, x, 0,7)的递归调用过程
10
6.3递归算法的设计方法
递归算法既是一种有效的算法设计方法,也是一种有效的分 析问题的方法。递归算法求解问题的基本思想是:对于一个较为 复杂的问题,把原问题分解成若干个相对简单且类同的子问题 ,这 样,原问题就可递推得到解。 适宜于用递归算法求解的问题的充分必要条件是: (1)问题具有某种可借用的类同自身的子问题描述的性质; (2)某一有限步的子问题(也称作本原问题)有直接的解存在。
mid = (low + high) / 2; if(x == a[mid]) return mid; else if(x < a[mid])
//查找不成功
//查找成功
return BSearch(a, x, low, mid-1); else return BSearch(a, x, mid+1, high); }
6.1递归的概念
若一个算法直接的或间接的调用自己本身,则称这 个算法是递归算法。 存在算法调用自己的情况:
(1)问题的定义是递推的
阶乘函数的常见定义是:
2
也可定义为:
写成函数形式了阶乘函数,称公式(6 – 3)是阶乘函数的递推定义式。
3
(2)问题的解法存在自调用 一个典型的例子是在有序数组中查找一个数 据元素是否存在的折半查找算法。
} //把n-1个圆盘从fromPeg借助toPeg移至auxPeg towers(n-1,fromPeg,auxPeg,toPeg);
//把圆盘n由fromPeg直接移至toPeg
12
图6-4 汉诺塔问题的递归求解示意图
13
算法设计:首先,盘子的个数n是必须的一个输入参数, 对n个盘子,我们可从上至下依次编号为1,2,…,n;其次, 输入参数还需有3个柱子的代号,我们令3个柱子的参数名 分别为fromPeg,auxPeg和toPeg;最后,汉诺塔问题的求 解是一个处理过程,因此算法的输出是n个盘子从柱子 fromPeg借助柱子auxPeg移动到柱子toPeg的移动步骤,我 们设计每一步的移动为屏幕显示如下形式的信息: Move Disk i from Peg X to Peg Y 这样,汉诺塔问题的递归算法可设计如下:
【原创】定制代写 r/python/spss/matlab/WEKA/sas /sql/C++/stata/eviews 数据挖掘 和统计分析可视化调研报告等 服务(附代码数据),咨询邮箱: glttom@ 有问题到淘 宝找“大数据部落”就可以了
图6-1 折半查找过程
4
6.2递归算法的执行过程
当一个问题存在上述两个基本要素时,该问题的递归算法的设 计方法是:
(1)把对原问题的求解设计成包含有对子问题求解的形式。
(2)设计递归出口。
11
例6-3 设计模拟汉诺塔问题求解过程的算法。汉诺塔问题的 描述是:设有3根标号为A,B,C的柱子,在A柱上放着n个盘子, 每一个都比下面的略小一点,要求把A柱上的盘子全部移到C柱 上,移动的规则是:(1)一次只能移动一个盘子;(2)移动 过程中大盘子不能放在小盘子上面;( 3 )在移动过程中盘子 可以放在A,B,C的任意一个柱子上。 问题分析:可以用递归方法求解n个盘子的汉诺塔问题。 基本思想:1个盘子的汉诺塔问题可直接移动。n个盘子的汉诺 塔问题可递归表示为,首先把上边的n-1个盘子从A柱移到B柱, 然后把最下边的一个盘子从A柱移到C柱,最后把移到B柱的n-1 个盘子再移到C柱。4个盘子汉诺塔问题的递归求解示意图如图 6-4所示。
//在下半区查找
//在上半区查找
8
测试主函数设计如下: # include <stdio.h>
main(void)
{ int a[] = {1, 3, 4, 5, 17, 18, 31, 33}; int x = 17; int bn; bn = BSearch(a, x, 0,7);
if(bn == -1) printf("x不在数组a中");
6
图6-2 Fact(3)的递归调用执行过程
7
例6-2 给出在有序数组a中查找数据元素x是否存在的 递归算法,并给出如图6-1所示实际数据的递归算法的 执行过程。递归算法如下:
int BSearch(int a[], int x, int low, int high)
{ int mid;
if(low > high) return -1;
long int Fact(int n) { int x; long int y; if(n < 0) { printf(“参数错!”); return -1; if(n == 0) return 1; else {y = Fact(n - 1); return n * y; } }
14
void towers(int n, char fromPeg, char toPeg, char auxPeg) { if(n==1) { //递归出口
printf("%s%c%s%c\n", "move disk 1 from peg ", fromPeg, " to peg ", toPeg); return;
5
//n < 0时阶乘无定义
}
//递归调用
设计主函数如下
void main(void)
{
long int fn; fn = Fact(3);
}
主函数用实参n= 3调用了递归算法Fact(3),而 Fact(3)要通过调用Fact(2)、Fact(2)要通过调用Fact(1)、 Fact(1)要通过调用Fact(0)来得出计算结果。Fact(3)的 递归调用过程如图6-2所示。
else printf("x在数组a的下标%d中", bn); }
9
BSearch(a, x, 0,7)的递归调用过程如图6-3所示, 其中,实箭头表示函数调用,虚箭头表示函数的返回值。
图6-3 BSearch(a, x, 0,7)的递归调用过程
10
6.3递归算法的设计方法
递归算法既是一种有效的算法设计方法,也是一种有效的分 析问题的方法。递归算法求解问题的基本思想是:对于一个较为 复杂的问题,把原问题分解成若干个相对简单且类同的子问题 ,这 样,原问题就可递推得到解。 适宜于用递归算法求解的问题的充分必要条件是: (1)问题具有某种可借用的类同自身的子问题描述的性质; (2)某一有限步的子问题(也称作本原问题)有直接的解存在。
mid = (low + high) / 2; if(x == a[mid]) return mid; else if(x < a[mid])
//查找不成功
//查找成功
return BSearch(a, x, low, mid-1); else return BSearch(a, x, mid+1, high); }
6.1递归的概念
若一个算法直接的或间接的调用自己本身,则称这 个算法是递归算法。 存在算法调用自己的情况:
(1)问题的定义是递推的
阶乘函数的常见定义是:
2
也可定义为:
写成函数形式了阶乘函数,称公式(6 – 3)是阶乘函数的递推定义式。
3
(2)问题的解法存在自调用 一个典型的例子是在有序数组中查找一个数 据元素是否存在的折半查找算法。
} //把n-1个圆盘从fromPeg借助toPeg移至auxPeg towers(n-1,fromPeg,auxPeg,toPeg);
//把圆盘n由fromPeg直接移至toPeg
12
图6-4 汉诺塔问题的递归求解示意图
13
算法设计:首先,盘子的个数n是必须的一个输入参数, 对n个盘子,我们可从上至下依次编号为1,2,…,n;其次, 输入参数还需有3个柱子的代号,我们令3个柱子的参数名 分别为fromPeg,auxPeg和toPeg;最后,汉诺塔问题的求 解是一个处理过程,因此算法的输出是n个盘子从柱子 fromPeg借助柱子auxPeg移动到柱子toPeg的移动步骤,我 们设计每一步的移动为屏幕显示如下形式的信息: Move Disk i from Peg X to Peg Y 这样,汉诺塔问题的递归算法可设计如下:
【原创】定制代写 r/python/spss/matlab/WEKA/sas /sql/C++/stata/eviews 数据挖掘 和统计分析可视化调研报告等 服务(附代码数据),咨询邮箱: glttom@ 有问题到淘 宝找“大数据部落”就可以了
图6-1 折半查找过程
4
6.2递归算法的执行过程
当一个问题存在上述两个基本要素时,该问题的递归算法的设 计方法是:
(1)把对原问题的求解设计成包含有对子问题求解的形式。
(2)设计递归出口。
11
例6-3 设计模拟汉诺塔问题求解过程的算法。汉诺塔问题的 描述是:设有3根标号为A,B,C的柱子,在A柱上放着n个盘子, 每一个都比下面的略小一点,要求把A柱上的盘子全部移到C柱 上,移动的规则是:(1)一次只能移动一个盘子;(2)移动 过程中大盘子不能放在小盘子上面;( 3 )在移动过程中盘子 可以放在A,B,C的任意一个柱子上。 问题分析:可以用递归方法求解n个盘子的汉诺塔问题。 基本思想:1个盘子的汉诺塔问题可直接移动。n个盘子的汉诺 塔问题可递归表示为,首先把上边的n-1个盘子从A柱移到B柱, 然后把最下边的一个盘子从A柱移到C柱,最后把移到B柱的n-1 个盘子再移到C柱。4个盘子汉诺塔问题的递归求解示意图如图 6-4所示。
//在下半区查找
//在上半区查找
8
测试主函数设计如下: # include <stdio.h>
main(void)
{ int a[] = {1, 3, 4, 5, 17, 18, 31, 33}; int x = 17; int bn; bn = BSearch(a, x, 0,7);
if(bn == -1) printf("x不在数组a中");
6
图6-2 Fact(3)的递归调用执行过程
7
例6-2 给出在有序数组a中查找数据元素x是否存在的 递归算法,并给出如图6-1所示实际数据的递归算法的 执行过程。递归算法如下:
int BSearch(int a[], int x, int low, int high)
{ int mid;
if(low > high) return -1;