站长百科 | 数字化技能提升教程 数字化时代生存宝典
首页
数字化百科
电子书
▼
建站程序
开发
服务器
办公软件
开发教程
▼
服务器教程
软件使用教程
运营教程
热门电子书
▼
CSS教程
WordPress教程
导航
程序频道
推广频道
网赚频道
人物频道
网站程序
网页制作
云计算
服务器
CMS
论坛
网店
虚拟主机
cPanel
网址导航
WIKI使用导航
WIKI首页
热点词条
最新资讯
网站程序
站长人物
页面分类
使用帮助
编辑测试
创建条目
网站地图
站长百科导航
站长百科
主机侦探
IDCtalk云说
跨境电商导航
WordPress啦
站长专题
网站推广
网站程序
网站赚钱
虚拟主机
cPanel
网址导航专题
云计算
微博营销
虚拟主机管理系统
开放平台
WIKI程序与应用
美国十大主机
编辑“
C语言教程/第五章:函数3
”(章节)
人物百科
|
营销百科
|
网赚百科
|
站长工具
|
网站程序
|
域名主机
|
互联网公司
|
分类索引
跳转至:
导航
、
搜索
警告:
您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您
登录
或
创建
一个账户,您的编辑将归属于您的用户名,且将享受其他好处。
反垃圾检查。
不要
加入这个!
==函数的递归调用== 一个函数在它的函数体内调用它自身称为递归调用。 这种函数称为递归函数。C语言允许函数的递归调用。在递归调用中, 主调函数又是被调函数。执行递归函数将反复调用其自身。 每调用一次就进入新的一层。例如有函数f如下: <pre> int f (int x) { int y; z=f(y); return z; }</pre> 这个函数是一个递归函数。 但是运行该函数将无休止地调用其自身,这当然是不正确的。为了防止递归调用无终止地进行, 必须在函数内有终止递归调用的手段。常用的办法是加条件判断, 满足某种条件后就不再作递归调用,然后逐层返回。 下面举例说明递归调用的执行过程。 [例5.9]用递归法计算n!用递归法计算n!可用下述公式表示: <pre> n!=1 (n=0,1) n×(n-1)! (n>1) 按公式可编程如下: long ff(int n) { long f; if(n<0) printf("n<0,input error"); else if(n==0||n==1) f=1; else f=ff(n-1)*n; return(f); } main() { int n; long y; printf("\ninput a inteager number:\n"); scanf("%d",&n); y=ff(n); printf("%d!=%ld",n,y); } long ff(int n) { …… else f=ff(n-1)*n; …… } main() { …… y=ff(n); …… } </pre> 程序中给出的函数ff是一个递归函数。主函数调用ff 后即进入函数ff执行,如果n<0,n==0或n=1时都将结束函数的执行,否则就递归调用ff函数自身。由于每次递归调用的实参为n-1,即把n-1 的值赋予形参n,最后当n-1的值为1时再作递归调用,形参n的值也为1,将使递归终止。然后可逐层退回。下面我们再举例说明该过程。 设执行本程序时输入为5, 即求 5!。在主函数中的调用语句即为y=ff(5),进入ff函数后,由于n=5,不等于0或1,故应执行f=ff(n-1)*n,即f=ff(5-1)*5。该语句对ff作递归调用即ff(4)。 逐次递归展开如图5.3所示。进行四次递归调用后,ff函数形参取得的值变为1,故不再继续递归调用而开始逐层返回主调函数。ff(1)的函数返回值为1,ff(2)的返回值为1*2=2,ff(3)的返回值为2*3=6,ff(4) 的返回值为6*4=24,最后返回值ff(5)为24*5=120。 例5. 9也可以不用递归的方法来完成。如可以用递推法,即从1开始乘以2,再乘以3…直到n。递推法比递归法更容易理解和实现。但是有些问题则只能用递归算法才能实现。典型的问题是Hanoi塔问题。 [例5.10]Hanoi塔问题 一块板上有三根针,A,B,C。A针上套有64个大小不等的圆盘, 大的在下,小的在上。如图5.4所示。要把这64个圆盘从A针移动C针上,每次只能移动一个圆盘,移动可以借助B针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。求移动的步骤。 <pre> 本题算法分析如下,设A上有n个盘子。 如果n=1,则将圆盘从A直接移动到C。 如果n=2,则: 1.将A上的n-1(等于1)个圆盘移到B上; 2.再将A上的一个圆盘移到C上; 3.最后将B上的n-1(等于1)个圆盘移到C上。 如果n=3,则: A. 将A上的n-1(等于2,令其为n`)个圆盘移到B(借助于C), 步骤如下: (1)将A上的n`-1(等于1)个圆盘移到C上,见图5.5(b)。 (2)将A上的一个圆盘移到B,见图5.5(c) (3)将C上的n`-1(等于1)个圆盘移到B,见图5.5(d) B. 将A上的一个圆盘移到C,见图5.5(e) C. 将B上的n-1(等于2,令其为n`)个圆盘移到C(借助A), 步骤如下: (1)将B上的n`-1(等于1)个圆盘移到A,见图5.5(f) (2)将B上的一个盘子移到C,见图5.5(g) (3)将A上的n`-1(等于1)个圆盘移到C,见图5.5(h)。 到此,完成了三个圆盘的移动过程。 从上面分析可以看出,当n大于等于2时, 移动的过程可分解为 三个步骤: 第一步 把A上的n-1个圆盘移到B上; 第二步 把A上的一个圆盘移到C上; 第三步 把B上的n-1个圆盘移到C上;其中第一步和第三步是类同的。 当n=3时,第一步和第三步又分解为类同的三步, 即把n`-1个圆盘从一个针移到另一个针上,这里的n`=n-1。 显然这是一个递归过 程,据此算法可编程如下: </pre> <pre> move(int n,int x,int y,int z) { if(n==1) printf("%c-->%c\n",x,z); else { move(n-1,x,z,y); printf("%c-->%c\n",x,z); move(n-1,y,x,z); } } main() { int h; printf("\ninput number:\n"); scanf("%d",&h); printf("the step to moving %2d diskes:\n",h); move(h,'a','b','c'); } move(int n,int x,int y,int z) { if(n==1) printf("%-->%c\n",x,z); else { move(n-1,x,z,y); printf("%c-->%c\n",x,z); move(n-1,y,x,z); } } main() { …… move(h,'a','b','c'); }</pre> 从程序中可以看出,move函数是一个递归函数,它有四个形参n,x,y,z。n表示圆盘数,x,y,z分别表示三根针。move 函数的功能是把x上的n个圆盘移动到z 上。当n==1时,直接把x上的圆盘移至z上,输出x→z。如n!=1则分为三步:递归调用move函数,把n-1个圆盘从x移到y;输出x→z;递归调用move函数,把n-1个圆盘从y移到z。在递归调用过程中n=n-1,故n的值逐次递减,最后n=1时,终止递归,逐层返回。当n=4 时程序运行的结果为 <pre> input number: 4 the step to moving 4 diskes: a→b a→c b→c a→b c→a c→b a→b a→c b→c b→a c→a b→c a→b a→c b→c </pre>
摘要:
请注意,您对站长百科的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。
您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅
Wordpress-mediawiki:版权
的细节)。
未经许可,请勿提交受版权保护的作品!
取消
编辑帮助
(在新窗口中打开)