收藏 分享(赏)

第4章 递归.ppt

上传人:yjrm16270 文档编号:8355932 上传时间:2019-06-22 格式:PPT 页数:31 大小:1.21MB
下载 相关 举报
第4章  递归.ppt_第1页
第1页 / 共31页
第4章  递归.ppt_第2页
第2页 / 共31页
第4章  递归.ppt_第3页
第3页 / 共31页
第4章  递归.ppt_第4页
第4页 / 共31页
第4章  递归.ppt_第5页
第5页 / 共31页
点击查看更多>>
资源描述

1、教学要求 了解递归算法的概念与递归设计要领 掌握应用递归算法求解排序与选择、实现排列组合等典型案例 了解递归算法中的回溯过程 本章重点 递归关系与边界条件的探求与确定,第 4 章 递 归,4.1 分治策略与递归,1. 分治策略 (1) 当求解一个规模很大的问题时,可以考虑分解,即把原问题分解为若干个较小规模的问题处理,以便各个击破,分而治之,这就是分治的设计思想。 (2) 如果求解的问题可分解为k个子问题,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,这种分治是可行的。 (3) 通过例4-1 棋盘覆盖问题理解分治策略的应用。,2. 递归 (1) 递归(Recursion)是一个过程

2、或函数在其定义中直接或间接调用自身的一种方法,就是利用系统堆栈,实现函数自身调用或相互调用的过程。在通往边界的过程中,都会把单步地址保存下来,再按照先进后出进行运算。 (2) 递归算法通过函数或过程调用自身将问题转化为本质相同但规模较小的子问题,是分治策略的具体体现。 (3) 递归需要有递归关系式与边界条件,递归过程有递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。,3. 递归关系与边界条件,(1) 递归设计需要有递归关系,这是递归的依据;同时需要有边界条件,这是递归的基础,是控制递归过程结束的条件。 (2) 递归过程分为递归前进段和递归返回段。当边界条件不满

3、足时,递归前进;当边界条件满足时,递归返回。 (3)编写递归函数,并设计主函数调用递归函数。,例4-2 应用递归计算n!。计算整数n的阶乘n!是一个典型的递归问题。使用递归方法来描述程序,十分简单且易于理解。 (1)描述递归关系注意到,当n1时,n!=n*(n1)!,这就是一种递归关系。对于特定的k!,它只与k和(k1)!有关。 (2)确定递归边界递归边界为: n=1时,n!=1。对于任意给定的n,程序将最终求解到1!。,4. 举例说明,http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ ht

4、tp:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.xunchi- http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.51xiu.org/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.gz- http:/www.gz- http:/ http:/ http:/ http:/ long f(int x) long g; if(x=0) printf(“x=0, 输入错误!“);

5、else if(x=1) g=1;else g=x*f(x1); return(g); (4)设计调用递归函数的主程序 void main() int n;long y;scanf(“%d“, ,(5) 递归调用的实现主函数调用f(n)后即进入函数f(n)执行。设执行本程序时输入为n=5,即求 5!。在主函数中的调用语句即为y=f(5),执行f函数,由于n=5,不等于1,故应执行g=n*f(n1),即g=5*f(4)。该语句调用f(4),进行4次递归调用后,f函数参数值变为1,故不再继续递归调用而开始逐层返回主调函数。f(1)的函数返回值为1,f(2)的返回值为2*1=2,f(3)的返回值为3

6、*2=6,f(4) 的返回值为4*6=24,最后返回值f(5)为5*24=120。,4.2 汉诺塔游戏,(1)有三根桩子A、B、C。A桩上有n个圆盘,最大的一个圆盘在底下,其余圆盘一个比一个小,依次叠上去。 (2)每次只移动一块圆盘,规定小盘的只能叠放在大盘的上面,而大盘不能叠放在小盘的上面。 (3)目标是把所有n个圆盘从A桩全部移到C桩上,如图4-4所示。 试求解n个圆盘从A桩全部移到C桩上的移动次数,并展示这n个圆盘的移动过程。,4.2.1 移动次数求解,设计要点:设移动n个盘需g(n)次完成。 (1) 首先将n个盘的上面的n-1个盘借助C桩从A桩移到B桩上,需g(n-1)次; (2) 然

7、后将A桩上最大的第n个盘移到C桩上,需1次; (3) 最后,将B桩上的n-1个盘借助A桩移到C桩上,需g(n-1)次。 因而有递归关系:g(n)=2*g(n-1)+1 初始条件(递归出口):g(1)=1,http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.xunchi- http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:

8、/ http:/ http:/www.51xiu.org/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.gz- http:/www.gz- http:/ http:/ http:/ http:/ 将A桩上面的m-1个盘借助C桩移到B桩上,即hn(m-1,a,c,b);(2) 将A桩上第m个盘移到C桩上,即mv(a,c);(3) 将B桩上的m-1个盘借助A桩移到C桩上,即hn(m-1,b,a,c)。在主程序中,带实参n, A,B,C调用hn(m,a,b,c),这里n为具体移动盘的个数。同时设置变量k统计移动的次数。,4.2.2 移动过

9、程实现,4.3 排队购票问题,4.3.1 常规排队一场球赛开始前,售票工作正在紧张进行中。每张球票为50元,有m+n个人排队等待购票,其中有m 个人手持50元的钞票,另外n个人手持100元的钞票。求出这m+n个人排队购票,使售票处不至出现找不开钱的局面的不同排队种数 。(约定:开始售票时售票处没有零钱,拿同样面值钞票的人对换位置为同一种排队。),递归设计要点,令f(m,n)表示有m个人手持50元的钞票,n个人手持100元的钞票时共有的排除总数。 分以下3种情况来讨论。 (1) n=0 n=0意味着排队购票的所有人手中拿的都是50元的钱币,注意到拿同样面值钞票的人对换位置为同一种排队,那么这m个

10、人的排队总数为1,即f(m,0)=1。 (2)mn 当mn时,即购票的人中持50元的人数小于持100元的钞票,即使把m张50元的钞票都找出去,仍会出现找不开钱的局面,这时排队总数为0,即f(m,n)=0。,http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.xunchi- http:/ http:/ http:/ http:/ http:/ http:/ http:/ http

11、:/ http:/ http:/www.51xiu.org/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.gz- http:/www.gz- http:/ http:/ http:/ http:/ 第m+n个人手持100元的钞票,则在他之前的m+n-1个人中有m个人手持50元的钞票,有n-1个人手持100元的钞票,此种情况共有f(m,n-1)。2) 第m+n个人手持50元的钞票,则在他之前的m+n-1个人中有m-1个人手持50元的钞票,有n个人手持100元的钞票,此种情况共有f(m-1,n)。由加法原理得到f(m,n)的递归关系:f

12、(m,n)=f(m,n-1)+f(m-1,n)初始条件:当mn时,f(m,n)=0当n=0时,f(m,n)=1,4.3.2 带条件限制的排队,为了满足“第5位为持50元”的规定,把图中左下角两条可位于第5位的“竖段”标注“”,列为禁止通过。这两段的上交叉点(4,1)与(3,2)就只能与其左边的(3,1)与(2,2)点发生关系,即if(j=4 ,4.4 多转向旋转方阵,递归设计要点:设计以顺转向内展开,设置二维数组a(h,v)存放方阵中第h行第v列元素。把n阶方阵从外到内分圈,外圈内是一个n-2阶顺转方阵,除起始数不同外,具有与原问题相同的特征属性。因此,设置旋转方阵递归函数t(b,s,d),其

13、中b为每个方阵的起始位置;s是方阵的阶数;d是为a数组赋值的整数。b赋初值0, 因方阵的起始位置为(0,0)。以后每一圈后进入下一内方阵,起始位置b需增1。d从1开始递增1取值,分别赋值给数组的各元素,至n2 为止。s从方阵的阶数n开始,以后每一圈后进入下一内方阵,s=s-2。若s1时,在函数t(b,s,d)中还需调用t(b+1,s-2,d)。至s=0时返回,作为递归的出口。,4.5 快速排序与选择,1.逐项比较排序最简单的排序是把存放在数组的n个数据逐个比较,必要时进行数据交换。n项逐项比较排序进行升序排序的算法描述如下:for(i=1;irj)t=ri;ri=rj;rj=t;逐项比较排序的

14、时间复杂度为O(n2)。,(1)快速排序思路快速排序又称为分区交换排序,其基本思想是分治,即分而治之:在待排序的n个数据r1,2,n中任取一个数(例如r1)作为基准,把其余n-1个数据分为两个区,小于基准的数放在左边,大于基准的数放在右边。这样分成的两个区实际上是待排序数据的两个子列。然后对这两个子列分别重复上述分区过程,直到所有子列只有一个元素,即所有元素排到位后,输出排序结果。,4.5.1 分区交换排序,http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ htt

15、p:/ http:/ http:/ http:/ http:/ http:/www.xunchi- http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.51xiu.org/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.gz- http:/www.gz- http:/ http:/ http:/ http:/ 分区交换描述,while(i!=j) while(rj=r0 / 把大于基准的一个数赋给r(j) ,(4)快速排序的时间复杂度分析,(

16、3) 快速排序实现 (实际测试算法),(1) 选择问题 在一个无序序列r(1),r(2),r(n)中,寻找第k小元素的问题称为选择。这里第k小元素是序列按升序排列后的第k个元素。特别地,当k=n/2时,即寻找位于n个元素中的中间元素,称为中值问题。,4.5.2 分区交换选择,(2) 选择问题的分区交换设计,参照上述分区交换的快速排序算法,在待选择的n个数据r1,2,n中任取一个数(例如r1)作为基准,把其余n-1个数据分为两个区,小于基准的数放在左边,大于基准的数放在右边,基准定位在s,则1) 若s=k,基准数即为所寻求的第k小元素。2) 若sk,可知左边小于该基准数的个数s-1k,则在左边的

17、子区继续分区。3) 若sk,可知所寻求的第k小元素在右边子区,则在右边的子区继续分区。依此2),3)继续,直到出现1)结束,输出结果。,(3) 快速选择的时间复杂度分析,4.6 实现排列组合,排列组合是组合数学的基础,从n个不同元素中任取m个,约定1mn,按任意一种次序排成一列,称为排列,其排列种数记为A(n,m)。从n个不同元素中任取m个(约定1mn)成一组,称为一个组合,其组合种数记为C(n,m)。计算A(n,m)与C(n,m)只要简单进行乘运算即可,要具体展现出排列的每一列与组合的每一组,决非轻而易举。本节应用递归设计来具体实现排列与组合。,1. 递归设计要点递归函数p(k)的变量k从1

18、开始取值。当km时,第k个数a(k)取i(1n),并标志量u=0。 (1)若a(k)与其前面已取的数a(j)(jk)比较,出现a(k)=a(j),即第k个数取i不成功,标志量u=1。 (2)若a(k)与所有前面已取的a(j)比较,没有一个相等,则第k个数取i成功,标志量保持u=0,然后判断:1) 若k=m,即已取了m个数,输出这m个数即为一个排列,a(k)继续从i+1开始,在余下的数中取一个数。直到全部取完,则返回上一次调用p(k)处,即回溯到p(k-1),第k-1个数继续往下取值。2) 若km,即还未取m个数,即在p(k)状态下调用p(k+1)继续探索下一个数,下一个数a(k+1)又从(1n

19、)中取数。,4.6.1 基本排列实现,http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.xunchi- http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.51xiu.org/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.g

20、z- http:/www.gz- http:/ http:/ http:/ http:/ (4)以上实现A(n,m)的递归深度为m,递归算法的时间复杂度为O(mn)。,4.6.3 组合实现,注意到组合与组成元素的顺序无关,约定组合中的组成元素按递增排序。因而,把以上排序程序中的约束条件作简单修改: “aj=ai” 修改为:“ aj=ai” “ak=aj” 修改为 :“ak=aj”即可实现从n个不同元素中取m个(约定1mn)的组合C(n,m)。这样修改实现组合的取值次数、判别次数均与实现排列相同,做了大量无效操作,效率太低。,1. 实现组合递归设计,约定组合中的组成元素递增排序,实现a 数组取

21、值的i循环设置为:for(i=ak-1+1;i=n+k-m;i+) ak=i;循环起点为:ak-1+1,即ak取值要比ak-1大,避免了元素取相同值的判别。循环终点为:n+k-m,即ak最大只能取n+k-m,为后面m-k个元素ak+1,am留下取值空间。显然a1需从1开始取值,因而循环前设置a0=0;递归函数c(k)中,ak取值后调用c(k+1),ak+1取值。当k=m时,输出一个组合;然后am继续往后取值,继续输出组合;直到am取值结束,返回即回溯到前c(m-1)状态, am-1 继续往后取值。最后c(1)状态中的a1取值结束,即返回主程序,输出组合数s。,注意到可重复的组成元素可以相同,因

22、而,把以上递归函数中ai的取值范围作简单修改:a0=1;for(i=ak-1;i=n;i+)即后一个元素可与前面的元素取值相同,每一个元素都可取到n。这样修改可实现从n个不同元素中取m个(约定1mn)可重复的组合。同时,在输出时注明“可重复”。,2. 实现可重复的组合递归设计,http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.xunchi- http:/ http:/ htt

23、p:/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.51xiu.org/ http:/ http:/ http:/ http:/ http:/ http:/ http:/www.gz- http:/www.gz- http:/ http:/ http:/ http:/ 递归与递推,递归与递推相比较: (1) 某些计数问题求解,可以相互替换例“排队购票”案例求解时,我们用了递归与递推两种算法设计。 (2) 在处理展示与构造性案例时,不能相互替代例应用递归设计展示汉诺塔移动过程,递推却难以实现。 (3) 递归的求解效率低于递推递归数据要不断的进栈出栈,且存在大量的重复计算。递推免除了数据进出栈的过程,直接从边界出发,逐步推出函数值,避免了重复计算。因而递推效率远远高于递归。,第4章作业,习题4: 1, 4, 5, 6, 7,第4章上机,(1) 上机通过本章汉诺塔问题、快速排序与选择、排列组合的实现等案例; (2) 上机通过整数的拆分式。 (3) 分组讨论:旋转方阵的各转向实现;递归与递推的区别(比较两种算法在“排队购票”的效率)。,返回,欢迎大家提出教学建议,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报