收藏 分享(赏)

第九讲 递归及其应用.ppt

上传人:w89153 文档编号:10201464 上传时间:2019-10-19 格式:PPT 页数:49 大小:545KB
下载 相关 举报
第九讲 递归及其应用.ppt_第1页
第1页 / 共49页
第九讲 递归及其应用.ppt_第2页
第2页 / 共49页
第九讲 递归及其应用.ppt_第3页
第3页 / 共49页
第九讲 递归及其应用.ppt_第4页
第4页 / 共49页
第九讲 递归及其应用.ppt_第5页
第5页 / 共49页
点击查看更多>>
资源描述

1、第九讲 递归,本讲主要内容:递归的定义 递归的工作原则 递归的执行过程 递归和非递归程序的差异 递归的应用,递归的定义,递归: 子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,称为递归。 递归是一种描述问题和解决问题的基本方法。,例如:void A() A(); 函数A中的语句直接调用了函数A本身,这叫做直接递归调用。,递归的定义,递归的定义,void B() void C() C(); B(); 在函数B中调用了函数C,而在函数C中又调用了B,这两个函数都通过另一个函数调用了它们自己,这就叫做间接递归调用。,递归的基本思想,问题分解:把一个不能或不好解决的大问题转化为一个或几个

2、小问题,再把这些小问题进一步分解成更小的小问题,直至每个小问题都可以直接解决。,递归的要素, 递归边界条件:确定递归到何时终止,也称为递归出口; 递归模式:大问题是如何分解为小问题的,也称为递归体。,例1 阶乘函数,递归算法 int fact ( int n ) if ( n = 0 ) return 1;else return n * fact (n-1); ,-,*,=,时,当,时,当,)!,1,(,1,!,n1,n0,n,n,n,应用举例递归,求解阶乘 n! 的过程,计算 fact(4),递归调用,回归求值,应用举例递归,递归过程与递归工作栈,递归过程在实现时,需要自己调用自己。 层层向

3、下递归,返回次序正好相反:递归调用n! (n-1)! (n-2)! 1!=1返回次序,应用举例递归,递归函数的内部执行过程,每一次递归调用时,需要为过程中使用的参数、局部变量等另外分配存储空间。 每层递归调用需分配的空间形成递归工作记录,按后进先出的栈组织。, 运行开始时,首先为递归调用建立一个工作栈,其结构包括值参、局部变量和返回地址; 每次执行递归调用之前,把递归函数的值参和局部变量的当前值以及调用后的返回地址压栈; 每次递归调用结束后,将栈顶元素出栈,使相应的值参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。,应用举例递归,例2. Fibonacci数列求解.,0 ,

4、当n=0,0, 1, 2, 3, 5, 8, 13, 21.,非递归求解: int f (int n) int pre, now, next, j;if (n=1) return (n);else pre=0; now=1;for(j=2;j=n;j+) next=pre+now;pre=now;now=next;return(next); ,递归求解: int f (int n) if (n=1) return (n);elsereturn (f(n-1)+f(n-2); ,递归程序与非递归程序的差异,递归与非递归程序的差别主要在于返回数据和备忘录的内存需求量.一般来说,非递归程序在时间及空

5、间上都比递归程序有效.在解决复杂问题的时候,可以侧重于用递归求解.,递归与非递归的比较,递归的应用,回文串 汉诺塔问题 迷宫问题 N皇后问题,回文串,如果一个字符串从左向右读和从右向左读完全相同(不区分大小写),则这个字符串称为回文串(palindrome),例如“noon”、“madam”等都是回文串。,可以用递归方法检测一个字符串S是否为回文串。 设S=“ShSh+1.St-1St”, h是第一个字符的位置,t是最后一个字符的位置。 1)若S是空串或长度为1,则S为回文串,否则: 2)若ShSt,则S不是回文串,否则,递归地检测S的子串“Sh+1.St-1”.,回文串,bool palin

6、drome(string ,递归的经典问题汉诺塔问题,在世界刚被创建的时候有一座钻石宝塔(塔A),其上有64个金碟。所有碟子按从大到小的次序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔(塔B和塔C)。从世界创始之日起,婆罗门的牧师们就一直在试图把塔A上的碟子移动到塔C上去,其间借助于塔B的帮助。每次只能移动一个碟子,任何时候都不能把一个碟子放在比它小的碟子上面。当牧师们完成任务时,世界末日也就到了。,汉诺塔问题,汉诺塔问题的递归求解:如果 n = 1,则将这一个盘子直接从 塔A移到塔 C 上。否则,执行以下三步: 将塔A上的n-1个碟子借助塔C先移到塔B上; 把塔A上剩下的一个碟子移到塔C

7、上; 将n-1个碟子从塔B借助于塔A移到塔C上。,应用举例递归,void Hanoi(int n, char A, char B, char C) if (n=1) Move(A, C); else Hanoi(n-1, A, C, B);Move(A, C);Hanoi(n-1, B, A, C); ,应用举例递归,Hanio(3,A,B,C),Hanio(2,A,C,B),Hanio(1,A,B,C),Move (A,C),Move (A,B),Hanio(1,C,A,B),Move (C,B),Move (A,C),Hanio(2,B,A,C),Hanio(1,B,C,A),Move (

8、B,C),Hanio(1,A,B,C),Move (A,C),Move (B,A), 写出函数当前调用层执行的各语句,并用有向弧表示语句的执行次序; 对函数的每个递归调用,写出对应的函数调用,从调用处画一条有向弧指向被调用函数入口,表示调用路线,从被调用函数末尾处画一条有向弧指向调用语句的下面,表示返回路线; 在返回路线上标出本层调用所得的函数值。,递归函数的运行轨迹,应用举例递归,出口,迷 宫 问 题,入口,在迷宫中求从入口到出口的所有路径是一 个经典的程序设计问题。迷宫可用下图所示的方块来表示,其中每个 元素或为通道(以空白方块表示),或为 墙(以带红色的方块表示)。迷宫问题要求的就是:从

9、入口到出口的一个以 空白方块构成的(无环)路径。,迷宫问题,迷宫问题 将迷宫表示为二维数组,入 口,出 口,求解迷宫问题的简单方法是:从入口出 发,沿某一方向进行探索,若能走通,则 继续向前走;否则沿原路返回,换一方向 再进行探索,直到所有可能的通路都探索 到为止。这类方法统称回溯法。,迷宫问题,求迷宫路径算法的基本思想是:,若当前位置“可通”,则纳入路径,继续前进;,若当前位置“不可通”,则后退,换方向继续探索;,若四周“均无通路”,则将当前位置从路径中删除出去。,出口,入 口,迷 宫 问 题,迷宫问题,回溯法(试探法)将问题的候选解按某一顺序逐一枚举和检验; 在回溯法中,放弃当前候选解,寻

10、找下一个候选解的过程叫做回溯.,迷宫问题,为了方便判断我们行走的下一步是否出界,我们假设迷宫的四周被墙壁包围。如下图:,入 口,出 口,迷宫可用二维数组mazemn来表示, 数组中元素为0的表示通道,为1的表示墙。 迷宫的入口处为maze11, 出口处为mazem-2n-2, 它们的元素值必为0。 任意时刻在迷宫中的位置可用元素的行下标和列下标(i,j)来表示。,迷宫问题,在位置(i,j)上,可往4个方向走,我们假设出发的优先级是往上、往下、往左、往右。每个点都按照这个优先级来决定下一点的方向。,在某一点mazeij时,可能的运动方向有四个。可以建立一个数组move4 给出相对于位置(i,j)

11、的四个方向上,i与j的增量值。 move数组的定义如下:typedef struct int vert;int horiz; offsets; offsets move4;,Move数组的值:,算法的实现 求迷宫中一条路径的算法,可以从入口开始,对每个“当前位置”都从上方向试起,若不能通过,则依次试验下方向、左方向、右方向。 当选定一个可通的方向,即找到“下一个位置”后,要把当前所在的位置纳入到探索路径中,并将当前所在的位置以及所选的方向记录下来,以便往下走不通时可顺原路一步步地退回来,每退一步以后接着试在该点上尚未试过的方向,从“下一个位置”开始继续探索,如此重复直至到达出口。,八皇后问题,

12、八皇后问题是一个古老而著名的问题,是递归算法的典型例题。 该问题是十九世纪著名的数学家高斯1850年提出: 在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。,八皇后问题,N皇后问题,高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解。后来有人用图论的方法解出92种结果。,N皇后问题求出在N*N的棋盘上放置N个棋子(皇后)的所有合法布局。布局合理规则是:在棋盘任一行、一列和任意对角线上都不能出现两个棋子。若两个皇后位于同一行、同一列、同一对角线上,则称为它们为互相攻击。n皇后问题是指找到这 n

13、 个皇后的互不攻击的布局。,要求: 1、用递归与非递归算法均可 2、从键盘输入N 3、输出所有合法布局,N皇后问题,1#主对角线 3#主对角线 5#主对角线,0#次对角线 2#次对角线 4#次对角线 6#次对角线,1#次对角线 3#次对角线 5#次对角线,0#主对角线 2#主对角线 4#主对角线 6#主对角线,0 1 2 3,0 1 2 3,k = i+j,k = n+i-j-1,解题思路,安放第 i 行皇后时,需要在列的方向从 0 到 n-1 试探 ( j = 0, , n-1 ) 在第 j 列安放一个皇后: 如果在列、主对角线、次对角线方向有其它皇后,则出现攻击,撤消在第 j 列安放的皇后

14、。 如果没有出现攻击,在第 j 列安放的皇后不动,递归安放第 i+1行皇后。,设置 4 个数组col n :coli 标识第 i 列是否安放了皇后md2n-1 : mdk 标识第 k 条主对角线是否安放了皇后sd2n-1 : sdk 标识第 k 条次对角线是否安放了皇后qn : qi 记录第 i 行皇后在第几列,void Queen( int i ) for ( int j = 0; j n; j+ ) if ( 第 i 行第 j 列没有攻击 ) 在第 i 行第 j 列安放皇后;if ( i = n-1 ) 输出一个布局;else Queen ( i+1 );撤消第 i 行第 j 列的皇后; ,算法求精void Queen( int i ) for ( int j = 0; j n; j+ ) if ( !colj /*在第 i 行第 j 列安放皇后*/,if ( i = n-1 ) /*输出一个布局*/for ( j = 0; j n; j+ ) printf(“%d,”, qj);printf(“n”);else Queen ( i+1 );colj = mdn+i-j-1 = sdi+j = 0;qi = 0; /*撤消第 i 行第 j 列的皇后*/ ,

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

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

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


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

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

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