C语言汉诺塔程序

C语言汉诺塔程序,第1张

将以下内容全部复制到新建的源文件中:(本人自己写的,因为你那课本上的代码,没解释,书写不规范,很难理解清楚,所以我直接新写了一个完整的代码,附带详细说明)

#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上搬过去的。

}

}

一开始我接触汉诺塔也是很不解,随着代码量的积累,现在很容易就看懂了,因此楼主主要还是对递归函数的理解不够深刻,建议你多写一些递归程序,熟练了自己就能理解。

圆盘逻辑移动过程+程序递归过程分析

hanoi塔问题, 算法分析如下,设a上有n个盘子,为了便于理解我将n个盘子从上到下编号1-n,标记为盘子1,盘子2......盘子n。

如果n=1,则将“ 圆盘1 ” 从 a 直接移动到 c。

如果n=2,则:

(1)将a上的n-1(等于1)个圆盘移到b上,也就是把盘1移动到b上;

(2)再将a上 “盘2” 移到c上;

(3)最后将b上的n-1(等于1)个圆盘移到c上,也就是第(1)步中放在b上的盘1移动到c上。

注意:在这里由于超过了1个盘子,因此不能直接把盘子从a移动到c上,要借助b,那

么 hanoi(n,one,two,three)的含义就是由n个盘子,从one移动到three,如果n>2

那么就进行递归,如果n=1,那么就直接移动。

具体流程:

hanoi(2,a,b,c);由于2>1因此进入了递归的环节中。

<1>执行hanoi(1,a,c,b):这里就是刚才的步骤(1),代表借助c柱子,将a柱子上的 1个圆盘(盘1)移动到b柱子,其实由于是n=1,此时c柱子并没被用到,而是直接移动了。

<2>执行hanoi(1,a,b,c):这是步骤(2),借助b柱子,将a柱子上的一个圆盘(盘2)移动到c柱子上。这里由于也是n=1,也并没有真正借助b柱子,直接移动的。

<3>执行hanoi(1,b,a,c):这是步骤(3),将b上的一个盘子(盘1)移动到c

函数中由于每次调用hanoi的n值都是1,那么都不会进入递归中,都是直接执行了mov移动函数。

如果n=3,则:(倒着想会想明白)移动的倒数第二部,必然是下面的情况

(1)将a上的n`-1(等于2)个圆盘移到c上,也就是将盘1、盘2 此时都在b柱子上,只有这样才能移动最下面的盘子(盘3)。那么由于现在我们先忽略的最大的盘子(盘3),那么我们现在的目标就是,将两个盘子(盘1、盘2)从a柱子上,借助c柱 子,移动到b柱子上来,这个过程是上面n=2的时候的移动过程,n=2的移动过程是“2 个盘子,从柱子a,借助柱子b,移动到柱子c”。现在是“2个盘子,从柱子a,借助柱子 c,移动到柱子b上”。因此移动过程直接调用n=2的移动过程就能实现。

(2)将a上的一个圆盘(盘3)移到c。

(3)到这一步,由于已经将最大的盘子(盘3)移动到了目的地,此时无论后面怎么移动都不需要在用到最大的那个盘子(盘3),我们就先忽略他,剩下的目标就是将b上面的n-1个盘子(盘1、盘2)移动到c上,由于a上没有盘子了,此时要完成上面的目标,就要借助a盘子。最终达到的目标就是将b上的2个盘子,借助a移动到c上,这个过程就是当n=2时分析的过程了,仅仅是最开始的柱子(b柱子)和被借助的柱子(a柱子)不同了。所以直接调用n=2时候的过程就能股实现了。

具体执行过程:

hanoi(3,a,b,c);由于3>1因此进入了递归的环节中。

<1>执行hanoi(2,a,c,b):这里代表刚才的步骤(1),将两个盘子(盘1、盘2)从a移动到b,中间借助c。根据n=2的分析过程,必然是能够达到我们的目的。

<2>执行hanoi(1,a,b,c):现在a上只有一个盘子(盘3),直接移动到c上面即可。

<3>执行hanoi(2,b,a,c):此时对应步骤(3),剩下的目标就是将b上的两个盘子,借助a移动到c上。那么同样根据n=2的移动过程,必然能达到目的。

最终实现了3个盘子从a,借助b移动到了c。

首先你得明白这是用函数递归调用的方法,递归就不用我说了,看代码

void

hanoi(int

n,char

one,char

two,char

three)

{

void

move(char

x,char

y)

if(n==1)

move(one,three)

//这个if语句,当盘子只有一个的时候,当然直接从第一根柱子(one)移到第//三根柱子(three)上就OK了,move(one,three)就这个意思!

else

{

hanoi(n-1,one,three,two)//当有n个盘子,按照递归法,调用hannoi,先把//上面的n-1个盘子从第一根柱子(one)借助第三根柱子(three)移到第二根柱//子上(two)。

move(one,three)//上面已把n-1个盘子移到第二根柱子上了,再将第一根柱//子剩下的一个盘子也就是最大的盘子从one移到three,明白?

hanoi(n-1,two,one,three)

/*移动好了最大的一个盘子,剩下n-1个盘子在two上,这时我们可以把第二根柱子与第一个柱//子的位置交换下,也就是标号为two的排第一,one排第二,three排第三。

这里的hanoi(n-1,two,one,three)对应

void

hanoi(int

n,char

one,char

two,char

three),只是盘子变成n-1

个,标号为two的柱子排第一了,下面要做的就是把two上上面的n-2个盘子借助three移到one上,再把剩下的一个移到第三个,再调换one

和two位置。

如此重复!注意转换位置只是我们头脑中的想象,程序本身没有转换柱子位置,编程完全按照标号(one

two

three)来实现的,我这样写只是便于理解递归过程,不知道是否理解?*/

}

}

void

move(char

x,char

y)

{

printf("%c-->%c\n",x,y)

}

/*move

函数只是起到一个打印步骤的作用,one对应‘A’,。。,比如move(one,two),就会打印出A-->B

*/

上面有些是我自己理解时的一些想法,希望能帮到你,实际你把代码对照算法多看几次就OK了,很容易的,理解了自己都可以写出来


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11257639.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存