第06章 指针.ppt
《第06章 指针.ppt》由会员分享,可在线阅读,更多相关《第06章 指针.ppt(39页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、存在算法调用自己的情况:存在算法调用自己的情况:若一个算法直接的或间接的若一个算法直接的或间接的调用自己本身调用自己本身,则称这,则称这个算法是递归算法。个算法是递归算法。(1 1)问题的定义是递推的)问题的定义是递推的阶乘阶乘函数的函数的常见定义常见定义是:是:6.16.1递归的概念递归的概念2也可也可定义为:定义为:写成写成函数形式,则为:函数形式,则为:这种函数定义的方法是这种函数定义的方法是用阶乘函数用阶乘函数自己本身定义了阶乘函数,自己本身定义了阶乘函数,称公式(称公式(63)是阶乘函数的)是阶乘函数的递推定义式递推定义式。3(2)问题的解法存在自调用)问题的解法存在自调用 一一个个
2、典典型型的的例例子子是是在在有有序序数数组组中中查查找找一一个个数数据元素是否存在的据元素是否存在的折半查找算法折半查找算法。图图6-1 6-1 折半查找过程折半查找过程 46.26.2递归算法的执行过程递归算法的执行过程 例例6-1 6-1 给给出出按按照照公公式式6-36-3计计算算阶阶乘乘函函数数的的递递归归算算法法,并给出并给出n=3n=3时递归算法的执行过程。时递归算法的执行过程。设计:按照公式设计:按照公式6-36-3计算阶乘函数的递归算法如下:计算阶乘函数的递归算法如下:longintFact(intn)intx;longinty;if(n0)/nhigh)return-1;/查
3、找不成功查找不成功mid=(low+high)/2;if(x=amid)returnmid;/查找成功查找成功elseif(xamid)returnBSearch(a,x,low,mid-1);/在下半区查找在下半区查找elsereturnBSearch(a,x,mid+1,high);/在上半区查找在上半区查找例例6-2给出在有序数组给出在有序数组a中查找数据元素中查找数据元素x是否存在的是否存在的递归算法,并给出如图递归算法,并给出如图6-1所示实际数据的递归算法的所示实际数据的递归算法的执行过程。递归算法如下:执行过程。递归算法如下:8测试主函数设计如下:测试主函数设计如下:#inclu
4、demain(void)inta=1,3,4,5,17,18,31,33;intx=17;intbn;bn=BSearch(a,x,0,7);if(bn=-1)printf(x不在数组不在数组a中中);elseprintf(x在数组在数组a的下标的下标%d中中,bn);9BSearchBSearch(a,x,0,7)(a,x,0,7)的递归调用过程如图的递归调用过程如图6-36-3所示,所示,其中,其中,实箭头表示函数调用,虚箭头表示函数的返回值实箭头表示函数调用,虚箭头表示函数的返回值。图图6-3 6-3 BSearchBSearch(a,x,0,7)(a,x,0,7)的递归调用过程的递归调
5、用过程 106.36.3递归算法的设计方法递归算法的设计方法 递递归归算算法法既既是是一一种种有有效效的的算算法法设设计计方方法法,也也是是一一种种有有效效的的分分析析问问题题的的方方法法。递递归归算算法法求求解解问问题题的的基基本本思思想想是是:对对于于一一个个较较为为复复杂杂的的问问题题,把把原原问问题题分分解解成成若若干干个个相相对对简简单单且且类类同同的的子子问问题题,这这样样,原问题就可递推得到解。原问题就可递推得到解。适宜于用递归算法求解的问题的适宜于用递归算法求解的问题的充分必要条件是:充分必要条件是:(1 1)问题具有某种可借用的类同自身的子问题描述的性质;)问题具有某种可借用
6、的类同自身的子问题描述的性质;(2 2)某一有限步的子问题(也称作本原问题)有直接的解存在。)某一有限步的子问题(也称作本原问题)有直接的解存在。当当一一个个问问题题存存在在上上述述两两个个基基本本要要素素时时,该该问问题题的的递递归归算算法法的的设设计计方法是:方法是:(1 1)把对原问题的求解设计成包含有对子问题求解的形式。)把对原问题的求解设计成包含有对子问题求解的形式。(2 2)设计递归出口。)设计递归出口。11例例6-3 6-3 设设计计模模拟拟汉汉诺诺塔塔问问题题求求解解过过程程的的算算法法。汉汉诺诺塔塔问问题题的的描描述述是是:设设有有3 3根根标标号号为为A A,B B,C C
7、的的柱柱子子,在在A A柱柱上上放放着着n n个个盘盘子子,每每一一个个都都比比下下面面的的略略小小一一点点,要要求求把把A A柱柱上上的的盘盘子子全全部部移移到到C C柱柱上上,移移动动的的规规则则是是:(1 1)一一次次只只能能移移动动一一个个盘盘子子;(2 2)移移动动过过程程中中大大盘盘子子不不能能放放在在小小盘盘子子上上面面;(3 3)在在移移动动过过程程中中盘盘子子可以放在可以放在A A,B B,C C的任意一个柱子上。的任意一个柱子上。问题分析问题分析:可以用递归方法求解可以用递归方法求解n n个盘子的汉诺塔问题。个盘子的汉诺塔问题。基本思想基本思想:1 1个盘子的汉诺塔问题可直
8、接移动。个盘子的汉诺塔问题可直接移动。n n个盘子的汉诺个盘子的汉诺塔问题可递归表示为,首先把上边的塔问题可递归表示为,首先把上边的n-1n-1个盘子从个盘子从A A柱移到柱移到B B柱,柱,然后把最下边的一个盘子从然后把最下边的一个盘子从A A柱移到柱移到C C柱,最后把移到柱,最后把移到B B柱的柱的n-1n-1个盘子再移到个盘子再移到C C柱。柱。4 4个盘子汉诺塔问题的递归求解示意图如图个盘子汉诺塔问题的递归求解示意图如图6-46-4所示。所示。12图图6-4 6-4 汉诺塔问题的递归求解示意图汉诺塔问题的递归求解示意图13算法设计:算法设计:首先,盘子的个数首先,盘子的个数n n是必
9、须的一个输入参数,是必须的一个输入参数,对对n n个盘子个盘子,我们可从上至下依次编号为我们可从上至下依次编号为1,2,1,2,n n;其次,其次,输入参数还需有输入参数还需有3 3个柱子的代号个柱子的代号,我们令我们令3 3个柱子的参数名个柱子的参数名分别为分别为fromPegfromPeg,auxPegauxPeg和和toPegtoPeg;最后,汉诺塔问题的求最后,汉诺塔问题的求解是一个处理过程,因此算法的输出是解是一个处理过程,因此算法的输出是n n个盘子从柱子个盘子从柱子fromPegfromPeg借助柱子借助柱子auxPegauxPeg移动到柱子移动到柱子toPegtoPeg的移动步
10、骤,我的移动步骤,我们设计每一步的移动为屏幕显示如下形式的信息:们设计每一步的移动为屏幕显示如下形式的信息:Move Disk i from Peg X to Peg YMove Disk i from Peg X to Peg Y这样,汉诺塔问题的这样,汉诺塔问题的递归算法可设计如下:递归算法可设计如下:14voidtowers(intn,charfromPeg,chartoPeg,charauxPeg)if(n=1)/递归出口递归出口printf(%s%c%s%cn,movedisk1frompeg,fromPeg,topeg,toPeg);return;/把把n-1个圆盘从个圆盘从fro
11、mPeg借助借助toPeg移至移至auxPegtowers(n-1,fromPeg,auxPeg,toPeg);/把圆盘把圆盘n由由fromPeg直接移至直接移至toPegprintf(%s%d%s%c%s%cn,movedisk,n,frompeg,fromPeg,topeg,toPeg);/把把n-1个圆盘从个圆盘从auxPeg借助借助fromPeg移至移至toPegtowers(n-1,auxPeg,toPeg,fromPeg);15测试主函数如下:测试主函数如下:#includevoidmain(void)Towers(4,A,C,B);程序运行的输出信息如下:程序运行的输出信息如下:
12、16MoveDisk1fromPegAtoPegBMoveDisk2fromPegAtoPegCMoveDisk1fromPegBtoPegCMoveDisk3fromPegAtoPegBMoveDisk1fromPegCtoPegAMoveDisk2fromPegCtoPegBMoveDisk1fromPegAtoPegBMoveDisk4fromPegAtoPegCMoveDisk1fromPegBtoPegCMoveDisk2fromPegBtoPegAMoveDisk1fromPegCtoPegAMoveDisk3fromPegBtoPegCMoveDisk1fromPegAtoPeg
13、BMoveDisk2fromPegAtoPegCMoveDisk1fromPegBtoPegC17 总结如下:总结如下:递归算法的执行过程是递归算法的执行过程是不断地自调用不断地自调用,直,直到到达递归出口才结束自调用过程;到达递归出口后,递到到达递归出口才结束自调用过程;到达递归出口后,递归算法开始按归算法开始按最后调用的过程最先返回最后调用的过程最先返回的次序返回;返回的次序返回;返回到最外层的调用语句时递归算法执行过程结束到最外层的调用语句时递归算法执行过程结束。186.46.4递归过程和运行时栈递归过程和运行时栈对于非递归函数,调用函数在调用被调用函数前,系统要对于非递归函数,调用函数
14、在调用被调用函数前,系统要保存保存以下两类以下两类信息信息:(1 1)调用函数的返回地址;)调用函数的返回地址;(2 2)调用函数的局部变量值。)调用函数的局部变量值。当执行完被调用函数,返回调用函数前,系统首先要当执行完被调用函数,返回调用函数前,系统首先要恢复恢复调用调用函数的函数的局部变量值局部变量值,然后,然后返回返回调用函数的调用函数的返回地址返回地址。递归函数被调用时,系统要作的工作和非递归函数被调用时递归函数被调用时,系统要作的工作和非递归函数被调用时系统要作的工作在系统要作的工作在形式上类同形式上类同,但,但保存信息的方法不同保存信息的方法不同。递归函数被调用时,系统的运行时栈
15、也要保存上述两类信息。递归函数被调用时,系统的运行时栈也要保存上述两类信息。每一层递归调用所需保存的信息构成运行时栈的一个工作记录,每一层递归调用所需保存的信息构成运行时栈的一个工作记录,在每进入下一层递归调用时,系统就建立一个新的在每进入下一层递归调用时,系统就建立一个新的工作记录工作记录,并,并把这个工作记录进栈成为运行时栈新的栈顶;每返回一层递归调把这个工作记录进栈成为运行时栈新的栈顶;每返回一层递归调用,就退栈一个工作记录。因为栈顶的工作记录必定是当前正在用,就退栈一个工作记录。因为栈顶的工作记录必定是当前正在运行的递归函数的工作记录,所以栈顶的工作记录也称为运行的递归函数的工作记录,
16、所以栈顶的工作记录也称为活动记活动记录。录。196.56.5递归算法的效率分析递归算法的效率分析斐波那契数列斐波那契数列Fib(n)Fib(n)的递推定义是:的递推定义是:求第求第n n项斐波那契数列的项斐波那契数列的递归函数递归函数如下:如下:longFib(intn)if(n=0|n=1)returnn;/递归出口递归出口elsereturnFib(n-1)+Fib(n-2);/递归调用递归调用20用归纳法可以证明求用归纳法可以证明求Fib(n)的递归的递归调用次数调用次数等于等于2n-1;计算斐波那契数列的递归函数计算斐波那契数列的递归函数Fib(n)的的时间复时间复杂度为杂度为O(2n
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第06章 指针 06
限制150内