㈠ c语言编程(汉诺塔问题)
move(n-1,x,z,y);——这句是调用函数,这个函数就是前面声明的:void move(int n,int x,int y,int z)
printf("%c-->%c",x,z);——这句是输出,%c 是指按CHAR型输出,"%c-->%c",就是输出两个CHAR型数据,中间用-->连接。而这两个CHAR的数据就是x和z。比如结果是:a-->c
move(n-1,y,x,z);——这句还是调用函数,这个函数就是前面声明的:void move(int n,int x,int y,int z)
㈡ C语言汉诺塔程序
将以下内容全部复制到新建的源文件中:(本人自己写的,因为你那课本上的代码,没解释,书写不规范,很难理解清楚,所以我直接新写了一个完整的代码,附带详细说明)
#include <stdio.h>
//汉诺塔x层塔从A塔整体搬到C塔,中间临时B塔。
//x层塔是从大到小往上叠放。每次移动只能移动一层塔。并且在移动过程中必须保证小层在上边
//借助B塔可以将x层塔全部从A搬到C上,并且符合要求(在移动过程中大的那块在下边,小的那块在上边)
int main()
{
void tower(int x,char a,char b,char c); //声明函数
int x=5,a='A',b='B',c='C'; //x表示有5层塔,具体要多少层自己修改这个值。abc分别表示ABC塔。
tower(x,a,b,c); //x层塔从a移动到c的全过程,主程序只有这条有效语句
return 0;
}
//以下是tower函数的定义
//参数解析:x层塔放在a上,b是中间塔,c是目标塔。即x层塔要从a搬到c上。
//此函数实现x层塔从a整体转移到c上。以及这个过程是怎么搬的全部过程。
void tower(int x,char a,char b,char c)
{
if(x==1)printf("将%d从%c放到%c\n",x,a,c); //只有1层塔时,直接从a搬到c上。
else //不止1层塔,则先将x-1层塔从a按照规律搬到b上,再将最后一块从a搬到c上,最后再将b上的x-1层塔按照规律搬到c上。
{
tower(x-1,a,c,b); //先将x-1层塔从a按照规律搬到b上,注意参数b放在最后,因为放在最后的参数是准备搬过去的目标塔。
printf("将%d从%c放到%c\n",x,a,c); //将最后一块从a搬到c上
tower(x-1,b,a,c); //最后再将b上的x-1层塔按照规律搬到c上,注意参数b放在开头,因为x-1层是要从b上搬过去的。
}
}
㈢ c语言 汉诺塔
因为if (n==1) printf("%c-->%c\n",a,c)这里少输入了一个分号档兆团,在后面加上;就可以行橘了
main()
{hanoi(3,'A','B','C');
}
hanoi(n,a,b,c)
int n;
char a,b,c;
{if (n==1) printf("%c-->%c\n"猜备,a,c);
else{hanoi(n-1,a,c,b);
printf("%c-->%c\n",a,c);
hanoi(n-1,b,a,c);}
}
㈣ 用c语言编写程序求汉诺塔的移动步骤
#include<stdio.h>
void move(char a,char b)
{
printf("%c->%c\n",a,b);
}
void f(int n,char a,char b,char c)
{
if(n==1) move(a,c);
else
{
f(n-1,a,c,b);
move(a,c);
f(n-1,b,a,c);
}
}
void main()
{
int n;
scanf("%d",&n);
f(n,'a','b','c');
}
这是我的代码 前面的是定义一个函数 这里递归体现在函数里面还有函数 于是会一次又一次的计算 直到最后把N-1以前的都移到B,最下面的移到C,再把其他的从B移到C。。 无返回的话 应该是这里用void 没有return返回数值
㈤ C语言汉诺塔(高分提问)
其实汉诺塔就是递归问题,你理解了递归思想,自然就很容易懂,这种问题一般都作为编程语言教程的递归例子讲解的,你其实可以仔细看看课本的.
hanio(n-1,a,c,b);// 这语句的意思是:首先将a 上面的n-1个盘通过c 移动到b ,这样的结果是,a 只剩下最大一块盘,然后直接移动到c就行了,所以也就有move(a,c); 之后a 为空,b 有刚才移动的n-1个盘,c 上面已经有个最大的了,如果把剩下的n-1移动到c ,就完成了,所以接着有下面的语句:
hanio(n-1,b,a,c); //这意思说,把b 上的n-1个盘通过a 移动到c,
就这样完成递归,一次次执行下去,就行了.
㈥ C语言汉诺塔
根据汉诺塔的游戏规则可知,若只有一个盘子,则只要直接搬运就可以了,其它的不需要再做。return语句的作用,就是遇到它时,程序直接返回到调用它的地方,不再执行此函数中return语句以后的代码。
不过这里这个return语句也可以不写,只是代码要稍作更改(代码的执行还是不变的,即与更改前完全等价):
voidhanNuoTa(intn,charfrom,charto,charhelper)
{
if(n==1)
{
printf("%c--->%c ",from,to);
}
else
{
hanNuoTa(n-1,from,helper,to);
printf("%c--->%c ",from,to);
hanNuoTa(n-1,helper,to,from);
}
}
㈦ C语言实验题——汉诺塔
【例】Hanoi塔问题
一块板上有三根针,A,B,C。A针上套有64个大小不等的圆盘,大的在下,小的在上。如图5.4所示。要把这64个圆盘从A针移动C针上,每次只能移动一个圆盘,移动可以借助B针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。求移动的步骤。
本题算法分析如下,设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上。
(2)将A上的一个圆盘移到B。
(3)将C上的n`-1(等于1)个圆盘移到B。
B. 将A上的一个圆盘移到C。
C. 将B上的n-1(等于2,令其为n`)个圆盘移到C(借助A),步骤如下:
(1)将B上的n`-1(等于1)个圆盘移到A。
(2)将B上的一个盘子移到C。
(3)将A上的n`-1(等于1)个圆盘移到C。
到此,完成了三个圆盘的移动过程。
从上面分析可以看出,当n大于等于2时,移动的过程可分解为三个步骤:
第一步 把A上的n-1个圆盘移到B上;
第二步 把A上的一个圆盘移到C上;
第三步 把B上的n-1个圆盘移到C上;其中第一步和第三步是类同的。
当n=3时,第一步和第三步又分解为类同的三步,即把n`-1个圆盘从一个针移到另一个针上,这里的n`=n-1。 显然这是一个递归过程,据此算法可编程如下:
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函数是一个递归函数,它有四个形参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 时程序运行的结果为:
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
㈧ C语言函数递归调用汉诺塔问题
我一步步的给你讲,就会懂啦:
首先hanoi函数如果把当中的move函数给去掉,就变成了:
voidhanoi(intn,charone,chartwo,charthree)
{
if(n==1)
printf("%c->%c ",one,three);
else
{
hanoi(n-1,one,three,two);
printf("%c->%c ",one,three);
hanoi(n-1,two,one,three);
}
}
也就是把move(one,three),变成了printf("%c->%c ", one, three);。少了一个函数,更加清晰
所以这里的hanoi函数就有了执行的内容:printf
下面以3个盘子为例进行模拟计算机的执行过程:
1、hanoi(3,A,B,C),开始了这步,进入第一层函数,计算机在函数中会进行自我的再次调用(第7行代码)
2、(第7行):hanoi(2,A,C,B),于是这又是一个新的hanoi函数,这里我把它成为第二层函数
同样执行到第7行,卡住了,再次一次自我的调用
3、(进入第三层函数):hanoi(1,A,B,C),这里的第三层n=1,所以在第四行就显示出了"A->C",至此,第三层函数结束,回到调用他的第二层函数
4、在第二层当中,继续第8行的内容,所以显示出"A->B",继续运行,到第9行,开始了有一次自我调用
5、把她称为贰号第三层函数吧。。。hanoi(1,B,A,C),和第3步类似,这一层函数显示出了"B->C",然后结束函数,返回调用它的第二层函数
6、第二层函数执行完毕,返回调用它的第一层函数
7、第一层函数中执行到第8行,显示出"A->C",然后执行第9行:hanoi(2,B,A,C)
............
如果看到了这里理清楚了关系就会懂啦,接下来还有一半,如果都写下来就太复杂了-。-
你所说的空函数是指没有返回值,但是这里利用的是电脑调用函数的那种关系来解决的问题,比如上面的3步,会自动返回到第二层函数并继续
还可以这样理解汉诺塔,汉诺塔其实是将复杂的问题简单化,
先不管他有多少个盘子从A到C,我只把它视作3步
就像上面那样找个例子,反复的按照代码模拟计算机运行,过个五次六次,就会懂啦
㈨ 在C语言中用函数编写汉诺塔
*问题分析与算法设计
这是一个着名的问题,几乎所有的教材上都有这个问题。由于条件是一次只能移动一个盘,且不允许大盘放在小盘上面,所以64个盘的移动次数是:
18,446,744,073,709,551,615
这是一个天文数字,若每一微秒可能计算(并不输出)一次移动,那么也需要几乎一百万年。我们仅能找出问题的解决方法并解决较小N值时的汉诺塔,但很难用计算机解决64层的汉诺塔。
分析问题,找出移动盘乎渣穗子的正确算法。
首先考虑a杆下面的盘子而非杆上最上面的盘子,于是任务变成了:
*将上面的63个盘子移到b杆上;
*将a杆上剩下的盘子移到c杆上;
*将b杆上的全部盘子移到c杆上。
将这个过程继续下去,就是要先完成移动63个盘子、62个盘子、61个盘子....的工作。
为了更清楚地描述算法,可以定义一个函数movedisc(n,a,b,c)。该函数的功能是:将N个盘子从A杆上借助C杆移动到B杆上。这样移动N个盘子的工作就可以按照以下过程进行:
1) movedisc(n-1,a,c,b);
2) 将一个盘子从a移动到b上;
3) movedisc(n-1,c,b,a);
重复以上过程,直到将全部的盘子移动到位时为止。
*程序与程序注释
#include<stdio.h>
void movedisc(unsigned n,char fromneedle,char toneedle,char usingneedle);
int i=0;
void main()
{
unsigned n;
printf("please enter the number of disc:");
scanf("%d",&n); /*输入N值*/
printf("\tneedle:\ta\t b\t c\n");
movedisc(n,'a','c','b'); /*从A上借助B将N个盘子移动到C上*/
printf("\t Total: %d\n",i);
}
void movedisc(unsigned n,char fromneedle,char toneedle,char usingneedle)
{
if(n>0)
{
movedisc(n-1,fromneedle,usingneedle,toneedle);
/*从fromneedle上借助toneedle将N-1个盘子移动到usingneedle上*/
++i;
switch(fromneedle) /*将fromneedle 上的一个盘子移到toneedle上*/
{
case 'a': switch(toneedle)
{
case 'b': printf("\t[%d]:\t%2d.........>%2d\n",i,n,n);
break;
case 'c': printf("梁岁\t[%d]:\t%2d...............>%2d\n",i,n,n);
break;
}
break;
case 'b'岁卜: switch(toneedle)
{
case 'a': printf("\t[%d]:\t%2d<...............>%2d\n",i,n,n);
break;
case 'c': printf("\t[%d]:\t %2d........>%2d\n",i,n,n);
break;
}
break;
case 'c': switch(toneedle)
{
case 'a': printf("\t[%d]:\t%2d<............%2d\n",i,n,n);
break;
case 'b': printf("\t[%d]:\t%2d<........%2d\n",i,n,n);
break;
}
break;
}
movedisc(n-1,usingneedle,toneedle,fromneedle);
/*从usingneedle上借助fromneedle将N-1个盘子移动到toneedle上*/
}
}