c语言_递归算法_第1页
c语言_递归算法_第2页
c语言_递归算法_第3页
c语言_递归算法_第4页
c语言_递归算法_第5页
已阅读5页,还剩112页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1整理ppt计算机语言与程序设计计算机语言与程序设计谌谌 卫卫 军军Introduction to Computer Programming2整理ppt第第八章八章 递归算法递归算法基本概念基本概念基于回溯策略的递归基于回溯策略的递归基于分治策略的递归基于分治策略的递归 3整理ppt从前有座山,山上有座庙,庙里有一个老和尚从前有座山,山上有座庙,庙里有一个老和尚和一个小和尚,老和尚正在给小和尚讲故事。和一个小和尚,老和尚正在给小和尚讲故事。讲的是什么故事呢?他说,从前讲的是什么故事呢?他说,从前4整理pptRecursion- See Recursion. In order to unders

2、tand recursion, one must first understand recursion. 5整理pptC语言允许嵌套地调用函数,也就是说,在调用语言允许嵌套地调用函数,也就是说,在调用一个函数的过程中,又去调用另一个函数。一个函数的过程中,又去调用另一个函数。函数的嵌套调用函数的嵌套调用void main( ) study_english ( ); void study_english( ) reading( ); listening( ); writing( )void listening( ) 6整理ppt函数的嵌套调用有一个特例,即递归调用,也就函数的嵌套调用有一个特例,

3、即递归调用,也就是说,在调用一个函数的过程中,又出现了直接是说,在调用一个函数的过程中,又出现了直接或间接地去调用该函数本身。或间接地去调用该函数本身。void tell_story( ) int old_monk, young_monk; tell_story ( ); / tell_story 函数的递归调用函数的递归调用函数的递归调用函数的递归调用? ?7整理pptvoid tell_story( ) static int old_monk, young_monk; old_monk = old_monk + 1; / 年龄大了一岁年龄大了一岁 young_monk = young_mo

4、nk + 1; if(old_monk = 60) / 递归形式递归形式 tell_story ( ); else printf(对不起,已退休!对不起,已退休!); / 递归边界递归边界8整理ppt在语法上(简单)在语法上(简单)J递归即为普通的函数调用。递归即为普通的函数调用。在算法上(难)在算法上(难)J如何找到递归形式?如何找到递归形式?J如何找到递归边界?如何找到递归边界?如何编写递归程序?如何编写递归程序? 9整理ppt递归算法的类型递归算法的类型递归算法可以分为两种类型:递归算法可以分为两种类型: 基于分治策略的递归算法;基于分治策略的递归算法; 基于回溯策略的递归算法。基于回溯

5、策略的递归算法。10整理ppt第第八章八章 递归算法递归算法基本概念基本概念基于回溯策略的递归基于回溯策略的递归基于分治策略的递归基于分治策略的递归 11整理ppt分而治之(分而治之(divide-and-conquer)的算法)的算法设计思想:设计思想: Divide:把问题划分为若干个子问题;:把问题划分为若干个子问题; Conquer:以:以同样的方式同样的方式分别去处理各分别去处理各个子问题;个子问题;1. Combine:把各个子问题的处理结果综:把各个子问题的处理结果综合起来,形成最终的处理结果。合起来,形成最终的处理结果。8.2.1 分而治之分而治之12整理ppt玛特露什卡玛特露

6、什卡13整理ppt调用调用调用调用调用调用调用调用调用调用调用调用14整理ppt如何编写基于分治策略的递归程序?如何编写基于分治策略的递归程序?J在算法分析上,要建立分治递归的思维在算法分析上,要建立分治递归的思维方式。方式。J在编程实现上,要建立在编程实现上,要建立递归信心递归信心(To turst the recursion, Jerry Cain, stanford)。)。15整理ppt如何建立分治递归的思维方式?如何建立分治递归的思维方式?J基本原则:基本原则:目标驱动目标驱动!J计算计算n!:n! = n * (n-1)!,且,且1! = 1。递归形式递归形式递归边界递归边界16整理

7、ppt调用调用调用调用fact(3)fact(2)fact(1)17整理pptvoid main( ) int n; printf(请输入一个整数:请输入一个整数:); scanf(%d, &n); printf(%d! = %d n, n, fact(n);int fact(int n) if(n = 1) return(1); else return(n * fact(n-1);请输入一个整数:请输入一个整数:33! = 618整理ppt Bfact(2)fact(2)=2*fact(1)=2*fact(1)=2*1=2*1=2=2返回返回 DAfact(3)fact(3)=3*f

8、act(2)=3*fact(2)=3*2=3*2=6=6E E返回返回 Cfact(1)=1调用调用调用调用调用和返回的递归示意图调用和返回的递归示意图19整理ppt如何建立递归信心?如何建立递归信心?J函数的递归调用到底是如何进行的呢?函数的递归调用到底是如何进行的呢?在递归调用时,执行的是不是相同的代在递归调用时,执行的是不是相同的代码?访问的是不是相同的数据?如果是码?访问的是不是相同的数据?如果是的话,那么大家会不会相互干扰、相互的话,那么大家会不会相互干扰、相互妨碍?妨碍?20整理pptmain的栈帧的栈帧m3void main( ) int m; printf(请输入一个整数:请输

9、入一个整数:); scanf(%d, &m); printf(%d! = %dn, m, fact(m);int fact(int n) if(n = 1) return(1); else return(n * fact(n-1);3nfact的栈帧的栈帧2nfact的栈帧的栈帧1nfact的栈帧的栈帧21整理ppt8.2.2 寻找最大值寻找最大值问题描述:问题描述:给定一个整型数组给定一个整型数组a,找出其中的最大,找出其中的最大值。值。如何设计相应的如何设计相应的递归算法递归算法?22整理ppt如何来设计相应的递归算法?如何来设计相应的递归算法?目标:目标:maxa0, a1, a

10、n-1可分解为:可分解为:maxa0, maxa1, an-1另外已知另外已知maxx x这就是递归算法的这就是递归算法的递归形式递归形式和和递归边界递归边界,据,据此可以编写出相应的递归函数。此可以编写出相应的递归函数。23整理pptint Max(int a, int first, int n) int max; if(first = n-1) return afirst; max = Max(a, first+1, n); if(max R) return(-1); mid = (L + R)/2; if(x = bmid) return mid; else if(x bmid) ret

11、urn bsearch(b, x, L, mid-1); else return bsearch(b, x, mid+1, R);34整理ppt8.2.4 汉诺汉诺(Hanoi)(Hanoi)塔问题塔问题相传在古印度相传在古印度Bramah庙中,有位僧人整天把三根柱子庙中,有位僧人整天把三根柱子上的金盘倒来倒去,原来他是想把上的金盘倒来倒去,原来他是想把64个一个比一个小的个一个比一个小的金盘从一根柱子上移到另一根柱子上去。移动过程中遵金盘从一根柱子上移到另一根柱子上去。移动过程中遵守以下规则:每次只允许移动一只盘,且大盘不得落在守以下规则:每次只允许移动一只盘,且大盘不得落在小盘上(简单吗?

12、若每秒移动一只盘子,需小盘上(简单吗?若每秒移动一只盘子,需5800亿年亿年)ABC35整理ppt怎样编写这种程序?思路上还是先从最简单的情况分怎样编写这种程序?思路上还是先从最简单的情况分析起,搬一搬看,慢慢理出思路。析起,搬一搬看,慢慢理出思路。1、在、在A柱上只有一只盘子,假定盘号为柱上只有一只盘子,假定盘号为1, 这时只需将该盘直接从这时只需将该盘直接从A搬至搬至C,记为,记为 move from A to CABC136整理ppt2、在、在A柱上有二只盘子,柱上有二只盘子,1为小盘为小盘2为大盘。为大盘。分三步进行:分三步进行:ABC21move from A to B;move f

13、rom A to C;move form B to C;37整理ppt3、在、在A柱上有柱上有3只盘子,从小到大分别为只盘子,从小到大分别为1号,号,2号,号,3号。号。怎么移?怎么移?ABC213分七步!分七步!38整理ppt 分三步进行:分三步进行: move 2 discs from A to B using C; move from A to C; move 2 discs from B to C using A ;ABC21339整理ppt4、在、在A柱上有柱上有 n 个盘子个盘子, 从小到大分别为从小到大分别为1号、号、2号、号、3 号、号、n号。号。 第第 1 步:将步:将1号、

14、号、2号、号、n-1号盘作为一个整体,号盘作为一个整体, 在在C的帮助下,从的帮助下,从A移至移至B; 第第 2 步:将步:将n号盘从号盘从A移至移至C; 第第 3 步:再将步:再将1号、号、2号、号、n-1号盘作为一个整号盘作为一个整 体,在体,在A的帮助下,从的帮助下,从B移至移至C; 这三步记为:这三步记为: move n-1 discs from A to B using C; move 1 discs from A to C; move n-1 discs from B to C using A ;递归形式!递归形式!40整理ppt定义函数定义函数move(int n, char L

15、, char M, char R);表示表示move n discs from L to R using M;如果如果 n = 1,即表示,即表示move from L to R;移动的是谁?移动的是谁?41整理ppt#include void move(int n, char L, char M, char R);void main( ) int n; printf(请输入一个整数:请输入一个整数:); scanf(%d, &n); move(n, A, B, C);42整理ppt/ L: Left post, M: Middle post, R: Right postvoid mo

16、ve(int n, char L, char M, char R) if(n = 1) printf(move #1 from %c to %cn, L, R); else move(n-1, L, R, M); printf(move #%d from %c to %cn, n, L, R); move(n-1, M, L, R); 43整理ppt请输入一个整数:请输入一个整数:3move #1 from A to Cmove #2 from A to Bmove #1 from C to Bmove #3 from A to Cmove #1 from B to Amove #2 from

17、 B to Cmove #1 from A to C一次运行结果一次运行结果44整理ppt8.2.5 青蛙过河青蛙过河 一条小溪尺寸不大,青蛙可以从左岸跳到右岸,在左岸有一一条小溪尺寸不大,青蛙可以从左岸跳到右岸,在左岸有一石柱石柱L,面积只容得下一只青蛙落脚,同样右岸也有一石柱,面积只容得下一只青蛙落脚,同样右岸也有一石柱R,面积也只容得下一只青蛙落脚。有一队青蛙从尺寸上一个比一个面积也只容得下一只青蛙落脚。有一队青蛙从尺寸上一个比一个小。我们将青蛙从小到大,用小。我们将青蛙从小到大,用1,2,n编号。规定初始时这编号。规定初始时这队青蛙只能趴在左岸的石头队青蛙只能趴在左岸的石头L上,按编号

18、一个落一个,小的落在上,按编号一个落一个,小的落在大的上面。不允许大的在小的上面。在小溪中有大的上面。不允许大的在小的上面。在小溪中有S根石柱,有根石柱,有y片片荷叶,规定溪中的柱子上允许一只青蛙落脚,如有多只同样要求荷叶,规定溪中的柱子上允许一只青蛙落脚,如有多只同样要求按编号一个落一个,大的在下,小的在上,而且必须编号相邻。按编号一个落一个,大的在下,小的在上,而且必须编号相邻。对于荷叶只允许一只青蛙落脚,不允许多只在其上。对于右岸的对于荷叶只允许一只青蛙落脚,不允许多只在其上。对于右岸的石柱石柱R,与左岸的石柱,与左岸的石柱L一样允许多个青蛙落脚,但须一个落一一样允许多个青蛙落脚,但须一

19、个落一个,小的在上,大的在下,且编号相邻。当青蛙从左岸的个,小的在上,大的在下,且编号相邻。当青蛙从左岸的L上跳上跳走后就不允许再跳回来;同样,从左岸走后就不允许再跳回来;同样,从左岸L上跳至右岸上跳至右岸R,或从溪,或从溪中荷叶或溪中石柱跳至右岸中荷叶或溪中石柱跳至右岸R上的青蛙也不允许再离开。问在已上的青蛙也不允许再离开。问在已知溪中有知溪中有S根石柱和根石柱和y片荷叶的情况下,最多能跳过多少只青蛙?片荷叶的情况下,最多能跳过多少只青蛙?45整理ppt这题看起来较难,但是如果我们认真分析,理这题看起来较难,但是如果我们认真分析,理出思路,就可化难为易。出思路,就可化难为易。思路:思路:1、

20、简化问题,探索规律。先从个别再到一般,要善、简化问题,探索规律。先从个别再到一般,要善于对多个因素作分解,孤立出一个一个因素来分于对多个因素作分解,孤立出一个一个因素来分析,化难为易。析,化难为易。2. 定义函数定义函数 Jump ( S ,y ) 最多可跳过河的青蛙数最多可跳过河的青蛙数 其中:其中:S 河中柱子数河中柱子数 y 荷叶数荷叶数46整理ppt 2 说明:河中有一片荷叶,可以过两只青蛙,起始时说明:河中有一片荷叶,可以过两只青蛙,起始时 L 上有两上有两只青蛙,只青蛙,1# 在在 2# 上面。上面。 第一步:第一步:1# 跳到荷叶上;跳到荷叶上; 第二步:第二步:2# 从从 L

21、直接跳至直接跳至 R 上;上; 第三步:第三步:1# 再从荷叶跳至再从荷叶跳至 R 上。上。 如下图:如下图:2#2#1#1#2 21 13 3L L左岸左岸R R右岸右岸3. 先看简单情况,河中无柱子:先看简单情况,河中无柱子:S = 0 ,Jump ( 0 , y ) 当当 y = 1 时,时,Jump ( 0 , 1 ) = ;47整理ppt3 说明:河中有两片荷叶时,可以过说明:河中有两片荷叶时,可以过 3 只青蛙。起始时:只青蛙。起始时: 1#,2#,3# 3只青蛙落在只青蛙落在 L 上,上, 第一步:第一步:1# 从从 L 跳至叶跳至叶 1上,上, 第二步:第二步:2# 从从 L

22、跳至叶跳至叶 2上,上, 第三步:第三步:3# 从从 L 直接跳至直接跳至 R 上,上, 第四步:第四步:2# 从叶从叶 2 跳至跳至 R 上,上, 第五步:第五步:1# 从叶从叶 1 跳至跳至 R 上,上,叶1叶13 31 15 5L LR R叶2叶22 24 4采用归纳法:采用归纳法:Jump ( 0 , y ) = 当当 y = 2 时,时, Jump ( 0 , 2 ) = ; y+1; 意思是:在河中没有石柱的情况意思是:在河中没有石柱的情况下,过河的青蛙数仅取决于荷叶下,过河的青蛙数仅取决于荷叶数,数目是荷叶数数,数目是荷叶数+1。48整理ppt再看再看Jump( S, y )Ju

23、mp( S, y )先看一个最简单情况:先看一个最简单情况: S = 1,y = 1 。从图上看出需要从图上看出需要 步,跳过步,跳过 只青蛙。只青蛙。S SY Y5 54 46 6L LR R1 12 23 37 78 89 91#2#4#3#3#1#2#1#1# 9 4 9 4 1# 1# 青蛙从青蛙从 L L Y Y;2# 2# 青蛙从青蛙从 L L S S;1# 1# 青蛙从青蛙从 Y Y S S;3# 3# 青蛙从青蛙从 L L Y Y;4# 4# 青蛙从青蛙从 L L R R;3# 3# 青蛙从青蛙从 Y Y R R;1# 1# 青蛙从青蛙从 S S Y Y;2# 2# 青蛙从青蛙

24、从 S S R R;1# 1# 青蛙从青蛙从 Y Y R R;49整理ppt对于对于S = 1,y = 1的情形,从另外一个角度来分析的情形,从另外一个角度来分析若没有石柱若没有石柱S S,最多可过,最多可过 y+1y+1 = = 2 2 只青蛙。只青蛙。有了石柱有了石柱S后,最多可过后,最多可过 2*2 = 4 只青蛙。只青蛙。步骤步骤1 1:1#1#和和2# 2# 从从 L L S S;步骤步骤2 2:3#3#和和4# 4# 从从 L L R R;步骤步骤3 3:1#1#和和2# 2# 从从 S S R R;YSLR: 1#, 2#: 3#, 4#: 1#, 2#YYY50整理ppt对于对

25、于S = 1,y 1的情形的情形若没有石柱若没有石柱S S,最多可过,最多可过 y+1y+1 只青蛙。只青蛙。有了石柱有了石柱S后,最多可过后,最多可过 2*(y+1) 只青蛙。只青蛙。步骤步骤1 1:前前y+1y+1只只 从从 L L S S;步骤步骤2 2:后后y+1y+1只只 从从 L L R R;步骤步骤3 3:前前y+1y+1只只 从从 S S R R;YSLR: 前前y+1只只: 后后y+1只只: 前前y+1只只YYY51整理ppt对于对于S = 2,y 1的情形的情形若只有石柱若只有石柱S1,最多可过,最多可过 2 2* *(y+1)(y+1) 只青蛙。只青蛙。有了石柱有了石柱S

26、2后,最多可过后,最多可过 只青蛙。只青蛙。YS1LR4*(y+1)S2步骤步骤1 1:前前2*(y+1)只只 从从 L L S2 S2;步骤步骤2 2:后后2*(y+1)只只 从从 L L R R;步骤步骤3 3:前前2*(y+1)只只 从从 S2 S2 R R;Y,S1Y,S1Y,S152整理ppt采用归纳法,可得出如下的递归形式:采用归纳法,可得出如下的递归形式:Jump(S, y) = 2 * Jump(S-1, y);意思是:先让一半的青蛙利用意思是:先让一半的青蛙利用y片荷叶和片荷叶和S-1根石柱,落在河中剩下的那根石柱上;根石柱,落在河中剩下的那根石柱上;然后让另一半的青蛙利用然

27、后让另一半的青蛙利用y片荷叶和片荷叶和S-1根根石柱,落在右岸的石柱,落在右岸的R上面;最后再让先前上面;最后再让先前的一半青蛙,利用的一半青蛙,利用y片荷叶和片荷叶和S-1根石柱,根石柱,落在右岸的落在右岸的R上面。上面。递归边界:递归边界:Jump(0, y) = y + 153整理pptvoid main( ) int S, y; printf(请输入石柱和荷叶的数目:请输入石柱和荷叶的数目:); scanf(%d %d, &S, &y); printf(最多有最多有 %d 只青蛙过河只青蛙过河n, Jump(S, y);int Jump(int S, int y) if

28、(S = 0) return( y + 1 ); return( 2 * Jump(S-1, y);54整理ppt8.2.6 快速排序快速排序快速排序的基本思路:快速排序的基本思路:1 1、在数组、在数组a a中,有一段待排序的数据,下标从中,有一段待排序的数据,下标从l l到到r r。2 2、取、取alal放在变量放在变量valuevalue中,通过由右、左两边对中,通过由右、左两边对valuevalue的取值的比较,为的取值的比较,为valuevalue选择应该排定的位选择应该排定的位置。这时要将比置。这时要将比valuevalue大的数放右边,比它小的数大的数放右边,比它小的数放左边。当

29、放左边。当valuevalue到达最终位置后(如下标到达最终位置后(如下标m m),),由它划分了左右两个集合由它划分了左右两个集合l.m-1l.m-1、m+1.rm+1.r。然后转第然后转第1 1步,再用步,再用相同的思路相同的思路分别去处理左集合分别去处理左集合和右集合。和右集合。55整理ppt令令 qsort(l, r)表示将数组元素从下标为表示将数组元素从下标为 l 到到下标为下标为 r 的共的共 r-l+1 个元素进行从小到大的个元素进行从小到大的快速排序。快速排序。目标:目标:1、让、让 value = al2、将、将 value 放在放在 am中,中,l m r3、使、使 al,

30、 al+1, , am-1 = am4、使、使 am am+1, am+2, , ar56整理ppt例子:数组例子:数组a当中有当中有7个元素等待排序。个元素等待排序。5261734lr首先,让首先,让value = al = a0 = 5value5a0123456下标下标57整理ppt5261734l第二步,从第二步,从r=6开始,将开始,将ar与与value进行比较。进行比较。若若ar value,则,则 r-,继续比较。否则,继续比较。否则,al = ar,l +。value5ra0123456下标下标4l58整理ppt4261734第三步,从第三步,从l=1开始,将开始,将al与与v

31、alue进行比较。进行比较。若若al value,则,则 l+,继续比较。否则,继续比较。否则,ar = al,r -。value5ra0123456下标下标ll6r59整理ppt4261736又回到第二步,从又回到第二步,从r=5开始,将开始,将ar与与value进行进行比较。若比较。若ar value,则,则 r-,继续比较。否则,继续比较。否则al = ar,l +。 value5a0123456下标下标lr3l60整理ppt4231736又回到第三步,从又回到第三步,从l=3开始,将开始,将al与与value进行进行比较。若比较。若al value,则,则 l+,继续比较。否则,继续比

32、较。否则,ar = al,r -。 value5a0123456下标下标rll7r61整理ppt4231776现在现在 l r,已经找到了,已经找到了value的正确位置,把的正确位置,把value中的值放回到数组当中。中的值放回到数组当中。value5a0123456下标下标lr562整理ppt4231576下面的任务:用刚才介绍的方法,对下面的任务:用刚才介绍的方法,对 5 左、右左、右两侧的两段数据,分别进行排序。两侧的两段数据,分别进行排序。a0123456下标下标1324a0123456下标下标lr67a0123456下标下标lr63整理ppt1234567最后的结果:最后的结果:a

33、0123456下标下标具体实现:几重循环语句?具体实现:几重循环语句?参考程序:略参考程序:略64整理ppt第第八章八章 递归算法递归算法基本概念基本概念基于回溯策略的递归基于回溯策略的递归基于分治策略的递归基于分治策略的递归 65整理ppt 在程序设计当中,有相当一类求一组解、或求在程序设计当中,有相当一类求一组解、或求全部解或求最优解的问题,不是根据某种确定的全部解或求最优解的问题,不是根据某种确定的计算法则,而是利用试探和回溯(计算法则,而是利用试探和回溯(Backtracking)的搜索技术求解。回溯法也是设计递归算法的一种的搜索技术求解。回溯法也是设计递归算法的一种重要方法,它的求解

34、过程实质上是一个先序遍历一重要方法,它的求解过程实质上是一个先序遍历一棵棵“状态树状态树”的过程,只不过这棵树不是预先建立的,的过程,只不过这棵树不是预先建立的,而是隐含在遍历的过程当中。而是隐含在遍历的过程当中。66整理ppt8.3.1 分书问题分书问题有五本书,它们的编号分别为有五本书,它们的编号分别为1,2,3,4,5,现准备分给,现准备分给 A, B, C, D, E五个人,每个五个人,每个人的阅读兴趣用一个二维数组来加以描述:人的阅读兴趣用一个二维数组来加以描述:10 ijijlike ij 喜欢 书不喜欢 书希望编写一个程序,输出所有的分书方案,希望编写一个程序,输出所有的分书方案

35、,让人人皆大欢喜。让人人皆大欢喜。67整理ppt假定这假定这5个人对这个人对这5本书的阅读兴趣如下表:本书的阅读兴趣如下表: 1 2 3 4 5ABCDE0011011001011010001001001人人书书68整理ppt解题思路:解题思路:1、定义一个整型的二维数组,将上表中的阅读喜好、定义一个整型的二维数组,将上表中的阅读喜好用初始化的方法赋给这个二维数组。用初始化的方法赋给这个二维数组。可定义:可定义:int Like66 = 0, 0, 0,0,1,1,0, 0, 1,1,0,0,1, 0, 0,1,1,0,1, 0, 0,0,0,1,0, 0, 0,1,0,0,1;69整理ppt

36、2、定义一个整型一维数组、定义一个整型一维数组BookFlag6用来记录书用来记录书是否已被选用。用后五个下标作为五本书的标号,是否已被选用。用后五个下标作为五本书的标号,被选用的元素值为被选用的元素值为1, 未被选用的值为未被选用的值为0, 初始化皆为初始化皆为0.int BookFlag6 = 0;70整理ppt3、定义一个整型一维数组、定义一个整型一维数组BookTaken6用来记录用来记录每一个人选用了哪一本书。用数组元素的下标来作每一个人选用了哪一本书。用数组元素的下标来作为人的标号,用数组元素的值来表示书号。如果某为人的标号,用数组元素的值来表示书号。如果某个人还没有选好书,则相应

37、的元素值为个人还没有选好书,则相应的元素值为0。初始化。初始化时,所有的元素值均为时,所有的元素值均为0。int BookTaken6 = 0;4、循环变量、循环变量 i 表示人,表示人,j 表示书,表示书,i, j 1, 2, 3, 4, 571整理ppt一种方法:一种方法:枚举法枚举法。把所有可能出现的分书方案都枚举出来,把所有可能出现的分书方案都枚举出来,然后逐一判断它们是否满足条件,即是否然后逐一判断它们是否满足条件,即是否使得每个人都能够得到他所喜欢的书。使得每个人都能够得到他所喜欢的书。缺点:计算量太大。缺点:计算量太大。72整理ppti=1 j=1 j=2i=2j=3 j=5i=

38、3j=1i=3j=2 j=4i=4j=2 j=4i=4j=5i=5j=4 j=5 j=5 j=2i=5j=4 j=2 j=1 j=4i=4j=5 j=1i=5j=4 j=1i=3j=5i=2j=4如何抽取出如何抽取出递归形式?递归形式?73整理pptvoid person( int i );int Like66 = 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1;int BookFlag6 = 0;int BookTaken6 = 0;void main( )

39、 person( 1 );74整理pptvoid person(int i)/ 尝试给第尝试给第i个人分书个人分书 int j, k; for(j = 1; j = 5; j+)/ 尝试把每本书分给第尝试把每本书分给第i个人个人 if(BookFlagj != 0) | (Likeij = 0) continue; / 失败失败 BookTakeni = j; / 把第把第j本书分给第本书分给第i个人个人 BookFlagj = 1; if(i = 5)/ 已找到一种分书方案已找到一种分书方案 for(k = 1; k i, 表明这一步不可能走表明这一步不可能走 j 级台阶级台阶, 函函 数数

40、返回返回;否则,转第三步;否则,转第三步;第三步:这一步走第三步:这一步走 j 级台阶,即级台阶,即 paces = j; 如果如果 i - j = 0,说明已经到达地面了,也就是,说明已经到达地面了,也就是 已经找到一种方案了,把它显示出来;否则已经找到一种方案了,把它显示出来;否则 的话,接着走下一步,的话,接着走下一步,TryStep(i-j, s+1);第四步:第四步: j = j +1,如果,如果 j 3,转第二步;否则函数,转第二步;否则函数 结束。结束。能否用分治策略?能否用分治策略?80整理ppt8.3.3 八皇后问题八皇后问题在在8 88 8的棋盘上,放置的棋盘上,放置8 8

41、个个皇后皇后(棋子),使两两之(棋子),使两两之间互不攻击。所谓互不攻击是说任何两个皇后都要间互不攻击。所谓互不攻击是说任何两个皇后都要满足:满足:(1 1)不在棋盘的同一行;)不在棋盘的同一行;(2 2)不在棋盘的同一列;)不在棋盘的同一列;(3 3)不在棋盘的同一对角线上。)不在棋盘的同一对角线上。因此可以推论出,棋盘共有因此可以推论出,棋盘共有8 8行,故至多有行,故至多有8 8个皇后,个皇后,即每一行有且仅有一个皇后。这即每一行有且仅有一个皇后。这8 8个皇后中的每一个个皇后中的每一个应该摆放在哪一列上是解该题的任务。应该摆放在哪一列上是解该题的任务。81整理ppt82整理ppt数据的

42、定义(数据的定义(1):): i 第第i i行(个)皇后,行(个)皇后,1 1 i i 8 8; j 第第j列,列, 1 1 j j 8 8; Queeni 第第i i行皇后所在的列;行皇后所在的列; ColumnjColumnj 第第j j列是否列是否安全安全,0, 10, 1;83整理ppt 1 2 3 4 5 6 7 81234567884整理ppt数据的定义(数据的定义(2):): Down-7.7 记录每一条从上到下的对记录每一条从上到下的对 角线,是否安全,角线,是否安全,0,10,1 Up2.16 Up2.16记录每一条从下到上的对角记录每一条从下到上的对角 角线,是否安全,角线

43、,是否安全,0,10,185整理ppt利用以上的数据定义:利用以上的数据定义: 当我们需要在棋盘的当我们需要在棋盘的( i, j ) 位置摆放一个皇位置摆放一个皇后的时候,可以通过后的时候,可以通过Column数组、数组、Down数组和数组和Up数组的相应元素,来判断该位置数组的相应元素,来判断该位置是否安全;是否安全; 当我们已经在棋盘的当我们已经在棋盘的( i, j ) 位置摆放了一个位置摆放了一个皇后以后,就应该去修改皇后以后,就应该去修改Column数组、数组、Down数组和数组和Up数组的相应元素,把相应的数组的相应元素,把相应的列和对角线设置为不安全。列和对角线设置为不安全。86整

44、理pptvoid TryQueen( int i );int Queen9 = 0 ;int Column9 = 0 ;int Down15 = 0 ;int Up15 = 0 ;void main( ) TryQueen( 1 );87整理pptvoid TryQueen(int i)/ 摆放第摆放第 i 行的皇后行的皇后 int j, k; for(j = 1; j = 8; j+)/ 尝试把该皇后放在每一列尝试把该皇后放在每一列 if(Columnj | Downi-j+7 | Upi+j-2) continue; / 失败失败 Queeni = j; / 把该皇后放在第把该皇后放在第j

45、列上列上 Columnj = 1; Downi-j+7 = 1; Upi+j-2 = 1; if(i = 8)/ 已找到一种解决方案已找到一种解决方案 for(k = 1; k = 8; k+) printf(%d , Queenk); printf(n); else TryQueen(i + 1); / 摆放第摆放第i+1行的皇后行的皇后 Queeni = 0;/ 回溯,把该皇后从第回溯,把该皇后从第j列拿起列拿起 Columnj = 0; Downi-j+7 = 0; Upi+j-2 = 0; 88整理ppt共共92组解,部分答案如下:组解,部分答案如下:方案方案1:1 5 8 6 3 7

46、 2 4方案方案2:1 6 8 3 7 4 2 5方案方案3:1 7 4 6 8 2 5 3方案方案4:1 7 5 8 2 4 6 3方案方案5:2 4 6 8 3 1 7 5方案方案6:2 5 7 1 3 8 6 4方案方案7:2 5 7 4 1 8 6 3方案方案8:2 6 1 7 4 8 3 5方案方案9:2 6 8 3 1 4 7 5方案方案10:2 7 3 6 8 5 1 489整理pptn假设在假设在棋盘上事先已经摆放了一个国王棋盘上事先已经摆放了一个国王,位,位置为置为,即即第第X X行第行第Y Y列列,在摆放八个皇在摆放八个皇后时,要求皇后间不能互相攻击且不能被国后时,要求皇后

47、间不能互相攻击且不能被国王攻击。王攻击。国王的攻击范围如下图所示:国王的攻击范围如下图所示:思考题:对题目做如下的修改思考题:对题目做如下的修改90整理pptn先输入某一个皇后所在的位置先输入某一个皇后所在的位置,即第,即第X X行第行第Y Y列,列,在此情形下,如何摆放其余的在此情形下,如何摆放其余的7 7个个皇后,要求找到所有解决方案。皇后,要求找到所有解决方案。91整理ppt8.3.4 过河过河问题问题问题描述:问题描述:M条狼和条狼和N条狗(条狗(NM)渡船过河,从河西)渡船过河,从河西到河东。在每次航行中,该船最多能容纳到河东。在每次航行中,该船最多能容纳2只动物,只动物,且最少需搭

48、载且最少需搭载1只动物。安全限制:无论在河东、只动物。安全限制:无论在河东、河西还是船上,狗的数量不能小于狼的数量。河西还是船上,狗的数量不能小于狼的数量。请问:能否找到一种方案,使所有动物都能顺利过请问:能否找到一种方案,使所有动物都能顺利过河。如果能,移动的步骤是什么?河。如果能,移动的步骤是什么?92整理ppt如何描述系统的当前状态?如何描述系统的当前状态? 位置:河西岸、河东岸、河;位置:河西岸、河东岸、河; 对象:船、狼、狗。对象:船、狼、狗。问题分析问题分析93整理ppt三元组三元组(W、 D、 B)WolfDogBoat例如:例如:(2, 2, W)94整理ppt若若M2、N2(

49、2, 2, W)(0, 2, E)(1, 2, W)(0, 0, E)(2, 0, W)(1, 0, E)95整理ppt 问题实质:在一个有向图中寻找一条问题实质:在一个有向图中寻找一条路径路径; 状态转换:如何从一个结点状态转换:如何从一个结点跳转跳转到另一个到另一个结点;结点; 状态树?状态树?问题分析问题分析96整理ppt 如何避免访问如何避免访问重复的重复的结点?结点? 如何用如何用简练的简练的语句实现状态的转换?语句实现状态的转换? 如何将如何将5种情形种情形归纳归纳为同一种形式?为同一种形式?技术难点技术难点97整理ppt#include #define MAX_M 20#defi

50、ne MAX_N 20int M, N;struct Status int W, D, B;steps1000;int s = 0, num = 0;int flagsMAX_MMAX_N2 = 0;void CrossRiver(int W, int D, int B);int IsValid(int w, int d, int b);98整理pptvoid main( ) scanf(%d %d, &M, &N); flagsMN0 = 1; steps0.W = M; steps0.D = N; steps0.B = 0; s = 1; CrossRiver(M, N,

51、0);void CrossRiver(int W, int D, int B) int i, j, f; int w, d, b;99整理ppt if(B = 0) f = -1; else f = 1; for(j = 1; j = 5; j+) switch(j) case 1: w = W + f*1; d = D; break; case 2: w = W + f*2; d = D; break; case 3: d = D + f*1; w = W; break; case 4: d = D + f*2; w = W; break; case 5: w = W + f*1; d =

52、D + f*1; break; b = 1 - B;100整理ppt if(IsValid(w, d, b) flagswdb = 1; stepss.W = w; stepss.D = d; stepss.B = b; s+; if(w = 0 & d = 0 & b = 1) num +; printf(Solutions %d: n, num); for(i = 0; i s; i+) printf(%d %d %dn, stepsi.W, stepsi.D, stepsi.B); else CrossRiver(w, d, b); flagswdb = 0; s-; 1

53、01整理pptint IsValid(int w, int d, int b) if(w M) return 0; if(d N) return 0; if(flagswdb = 1) return 0; if(d 0 & w d) return 0; if(N-d 0) & (M-w N-d) return 0; return 1;102整理ppt2 2Solutions 1:2 2 00 2 11 2 01 0 12 0 00 0 1Solutions 2:2 2 00 2 11 2 01 0 11 1 00 0 1Solutions 3:2 2 01 1 11 2 01

54、0 12 0 00 0 1Solutions 4:2 2 01 1 11 2 01 0 11 1 00 0 1103整理ppt8.3.5 排列排列问题问题n个对象的一个排列,就是把这个对象的一个排列,就是把这 n 个不同的个不同的对象放在同一行上的一种安排。例如,对于对象放在同一行上的一种安排。例如,对于三个对象三个对象 a, ,b, ,c,总共有,总共有6个排列:个排列:a b ca c bb a cb c ac a bc b an 个对象的排列个数就是个对象的排列个数就是 n!。104整理ppt如何生成排列?如何生成排列?基于分治策略的递归算法:基于分治策略的递归算法: 假设这假设这 n

55、个对象为个对象为 1, 2, 3, , n; 对于前对于前n-1个元素的每一个排列个元素的每一个排列 a1 a2 an-1,1 ai n-1,通过在所有可能的位置上插入通过在所有可能的位置上插入数字数字 n,来形成,来形成 n 个所求的排列,即:个所求的排列,即:n a1 a2 an-1a1 n a2 an-1a1 a2 n an-1 a1 a2 an-1 n105整理ppt例如:生成例如:生成1,2,3的所有排列的所有排列permutation(3) permutation(2) permutation(1)permutation(1):1permutation(2):2 1,1 2perm

56、utation(3):3 2 1,2 3 1,2 1 3, 3 1 2,1 3 2,1 2 3106整理ppt基于回溯策略的递归算法:基于回溯策略的递归算法: 基本思路:每一个排列的长度为基本思路:每一个排列的长度为 N,对这,对这N个不同的位置,按照顺序逐一地枚举所有个不同的位置,按照顺序逐一地枚举所有可能出现的数字。可能出现的数字。 定义一维数组定义一维数组NumFlagN+1用来记录用来记录1-N之之间的每一个数字是否已被使用,间的每一个数字是否已被使用,1表示已使表示已使用,用,0表示尚未被使用,初始化皆为表示尚未被使用,初始化皆为0;107整理ppt 定义一维数组定义一维数组NumTakenN+1,用来记录每,用来记录每一个位置上使用的是

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论