汉诺塔c语言执行步骤详解,详解汉诺塔执行过程

问题补充:

能否从以下开始详细像上面那样说明一下程序的运行过程吗?本人主要不知道函数的运行过程.

返回B第一次调用

6,向下执行,执行完毕,返回A第一次调用

7,本次函数中p=a,q=b,r=c,m=3,向下执行,输出a->c,执行B,调用本身(B第一次调用),传入q,p,r(b,a,c),m=2

8,p=b,q=a,r=c,m=2,执行A,调用本身(A'第一次调用,注意是B函数调用中再次调用A) 传入p,r,q(b,c,a)

9,p=b,q=c,r=a,m=1,执行if,输出b->a,返回A'第一次调用

10,本次函数中p=b,q=a,r=c,m=2向下执行,输出b->c,执行B,调用本身(B'的第一次调用,注意是B函数中再次调用B) 传入q,p,r(a,b,c),m=1

11,p=a,q=b,r=c,m=1,执行if,输出a->c返回B'第一次调用

12,向下执行,执行完毕,返回B第一次调用

13,向下执行,执行完毕,返回主函数

精彩回答:

递归其实很简单,你只要晓得啥子是嵌套调用就可以了,所谓嵌套调用,就是在一个函数里调用另一个函数,main函数不能被调用的,所以递归就是有限次的嵌套调用本身函数,每次调用,系统都会重新分配内存,返回时就返回上次调用他的那块内存中的调用函数处,这样理解应该很简单了

void move(int , char ,char,char);main(){int n;

printf("请输入盘数n=" );

scanf("%d",&n);

printf("在3根柱子上移%d只盘的步骤为:\n",n);

move(n,'a','b','c');}

void move(int m, char p, char q, char r) //定义函数

{if (m==1)

{printf("[%d] move 1# from %c to %c\n", step, p,r);

step=step+1;}

else{move(m-1,p,r,q); //调用本身函数,进行递归 A

printf("[%d] move %d# from %c to %c\n",step, m,p,r);

step=step+1;

move(m-1,q,p,r); //再次调用 B

}

getch();}

这里面的递归涉及一个汉诺塔的算法问题,具体讲明白的话有点麻烦,总体思路是假设盘子全在a柱上,想放到c上

第N个人就想要是有人搬动其他N-1个盘子到b,那他只要搬一次从a到c就可以,在让那个人把N-1个盘子放到c上

第N-1那个人就想要是有人搬动其他N-2个盘子到c,他只要搬动一次从a到b就可以,在让那个人把N-2个盘子放到b上

....

第1个人就直接把盘子从a到c

这样形成递归

我在俩处调用标记了A,B,我写出步踌,你看看.

假设3个盘子

A函数相当于双重循环中的外层循环

B函数相当于双重循环中的内层循环

1,主函数调用,p=a,q=b,r=c,m=3,运行A,调用本身(A第一次调用)传入p,r,q(a,c,b) 注意调用函数中p,r,q排列

2,被调函数是用p,q,r的顺序接收传入的p,r,q.p=a,q=c,r=b,m=2,执行A,调用本身(A第二次调用) 调用传p,r,q(a,b,c)

3,p=a,q=b,r=c,m=1,执行if,输出a->c,返回A第二次调用

4,本次函数中p=a,q=c,r=b,m=2,向下执行,输出a->b,执行B,调用本身(B第一次调用),传入q,p,r(c,a,b),m=1

5,p=c,q=a,r=b,m=1,执行if,输出c->b,返回B第一次调用

6,向下执行,执行完毕,返回A第一次调用

7,本次函数中p=a,q=b,r=c,m=3,向下执行,输出a->c,执行B,调用本身(B第一次调用),传入q,p,r(b,a,c),m=2

8,p=b,q=a,r=c,m=2,执行A,调用本身(A'第一次调用,注意是B函数调用中再次调用A) 传入p,r,q(b,c,a)

9,p=b,q=c,r=a,m=1,执行if,输出b->a,返回A'第一次调用

10,本次函数中p=b,q=a,r=c,m=2向下执行,输出b->c,执行B,调用本身(B'的第一次调用,注意是B函数中再次调用B) 传入q,p,r(a,b,c),m=1

11,p=a,q=b,r=c,m=1,执行if,输出a->c返回B'第一次调用

12,向下执行,执行完毕,返回B第一次调用

13,向下执行,执行完毕,返回主函数

a4c26d1e5885305701be709a3d33442f.png

仔细分析每次调用时当前变量p,q,r中所代表的a,b,c,每次调用时,p,q,r都是新的变量

我看了你的问题,估计你把调用函数中的p,q,r变量与被调函数中p,q,r变量搞混了

注意调用传入的顺序是q,p,r,传入的值是c,a,b的顺序,被调函数中是拿p,q,r的顺序在接收,所以被调函数中值的顺序就该是p=c,q=a,r=b,执行if就输出c->b

不要想太复杂了,q,p,r是变量,用来存储值的,而他只是个局部变量,每次调用函数后给q,p,r新分配的内存地址不一样。比如本次函数中q,p,r中放的值分别是q=c,p=a,r=b,当执行调用函数时,给被调函数传入的是变量的值,也就是说实际上传入的是c,a,b

在被调函数中,p,q,r是新的局部变量,他接收来自调用函数中的值,行参接收值的顺序与实参传入值的顺序是相对应的,因为实参传入的顺序是c,a,b,在行参接收值时也以这样的顺序接收,而行参变量的顺序是p,q,r,所以被调函数中p=c,q=a,r=b

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值