C语言实现汉诺塔问题(保姆式讲解)

article/2025/9/6 22:51:00

前言:

大家好,又是再一次分享文章,我十分感谢各位能够点开这篇花费我颇多时间才解决的汉诺塔问题,接下来我就要分享一下自己的所思所想,希望能给各位带来一些不一样的收获吧。

提醒:

汉诺塔问题的本质是函数递归,而函数递归已经是我们现阶段学习的C语言函数内容的后期知识,所以各位要想了解汉诺塔问题,请先学习好与函数有关的一些基本与重要的知识,还请各位多多理解。

说明:

我认为了解一个东西最重要是重复的实践,所以大家想要更好的了解汉诺塔问题,可在4399小游戏中或以其他方式去玩一玩,一定会加深你的认知的。


目录

1. 问题简述(以三层为例)

2. 背景

3. 数学思想

4. 执行过程的具体分析

(1) 过程简易分析(以三层为例)

(2) 思考

(3) 解答

(4) 递归说明

5. 整体代码及显示效果

6. 寄语


注意: 目录4.是整个汉诺塔问题最重要的部分,主要涉及了函数的递归问题,我会将每次的递归步骤在图纸上演示一遍(图有点丑,别嫌弃哈),以便大家更好的理解。我更希望如果各位真的想好好了解这个汉诺塔问题,就不要畏惧,其实并不难,认真看过程,我已经很详细地讲述我的理解了,希望能加深各位对汉诺塔问题的认识。


1. 问题简述(以三层为例)

(1)有三根柱子A,B,C。A柱上有n个盘子

(2)每次移动一个盘子,小的只能放在大的上面

(3)将所有盘子从A杆经过B杆全部移到C杆上d332a7d1b76a4712b551a988d7109efc.jpeg

2. 背景

法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

大家听了这个背景故事有没有对汉诺塔产生更大的兴趣呢,毕竟它与世界末日息息相关嘛,但是我们真的等得到那一天吗?

3. 数学思想

其实汉诺塔问题只是一个简单的数学问题,由分析易知:

如果考虑把64片金片,由一根柱子上移到另一根柱子上,并且始终保持上小下大的顺序。这需要多少次移动呢?这里可以先进行枚举,找到对应的数学规律假设有n片,移动次数是f(n)。则有:

747f7b98f0994c7593a579b2be09880a.png

由上述分析可以得到两个函数关系:   (1) f(n)=2^n-1  (2) f(n)=2*f(n-1)+1

而由我们之前在C语言中学到的函数递归知识可知,可以将数学函数关系式利用在代码中,形成一个求移动步数的函数递归式。相关代码如下:

9592b13668ac454b9f5748598d57f119.png

这样就可以简单的知道n层汉诺塔问题需要移动的步数了。

所以可知当n=64时,假如每秒钟一次,一个平年365天有31536000秒,闰年366天有31622400秒,平均每年31557600秒,计算得:18446744073709551615秒,大约5900亿年,可能到时太阳系真的毁灭了,但是我能肯定的是我以及各位怕是看不到那天了。

补充:在后面的刷题过程中,我遇到了一种汉诺塔问题的进阶题,就是移动盘子的过程中只能够相邻柱间移动,这里仅仅补充一下这个问题的结论——移动次数f(n)=3^n-1,就不多多介绍了,有兴趣的可以自己去了解下。

                                      重点知识前来张晚霞图,给各位放松放松哈

4. 执行过程的具体分析(重要理解)

(1) 过程简易分析(以三层为例)

30c3817e790d4c89af0d7ae229a43131.jpeg

起始柱命名为‘A’,中转柱命名为‘B’,目的柱命名为‘C’,所以可以得到操作顺序为:

A-->C,A-->B,C-->B,A-->C,B-->A,B-->C,A-->C;共七步。

7801316a842643089629b0ed4e1c45c9.jpeg

由上述简单分析可以得到汉诺塔问题的三步过程:

           一: 将n-1个盘子从A杆经过C杆移到B杆

968035b63c074169afab75ffdf7bd8b0.jpg

           二: 将A杆上第n个盘子移到C杆上

 d19d46eb6502426090698b83370cc6a9.jpg

           三: 将B杆上的n-1上盘子经过A杆移到C杆上

2aced34e629c47fc9e6fef3e761bb7e1.jpg

    这样经过三步后,一个汉诺塔就完成了。

(2) 思考

由上述分析也可以知道这是一个相似且反复的过程,因此由我们以往的经验也可以得出整个过程满足函数递归。而既然是一个函数递归问题,那就有两个问题我们值得思考。

(1) 这个递归的中相似的部分是什么?即要找到函数递归的条件。

(2) 这个递归的出口是什么?即我们要如何做才能趋于这个递归的出口,找到这个递归的终止语句。

解决这两个问题,我们也就能很好的理解汉诺塔问题中的函数递归。

(3) 解答

通过我们对三层汉诺塔的分析,我们可以知道汉诺塔问题的本质,即将A杆中的n个盘子通过B杆全部移到C杆上,这样我们就可以简单的写下这个函数HNtower(n,A,B,C),并且我们可以找到其中的相似部分。

(4) 递归说明

(1)要将A杆上的n-1个盘子通过C杆移到B杆(第一步)

这里就可以与我们定义的汉诺塔函数联系起来,而得出递归的第一层HNtower(n-1,A,C,B)

(2)要将B杆上的n-1个盘子通过A杆移到C杆上(第三步)

 这样可以得到递归的第二层HNtower(n-1,B,A,C)

但是,由三层汉诺塔也可以知道在函数递归过程中只有这两步也不够,我们除了找到这两个相似点外,还有一个十分重要的条件,那就是我们还需要在两步递归中定义调用一个移动函数Move(A,C);而由这个函数的两个参数我们也可以知道它的作用:将A杆的盘子移到C杆上(即在执行完第一步后,我们要将A杆上剩余的最大盘移到C杆上),即4c1f8404eb4d4ecbbeefbc4d29856667.png

递归出口:

找到这两层递归后,我们已经解决了汉诺塔问题的一半了,但是还有一个很重要的,也就是

这个递归的出口。而要找到这个出口,其实也不难,我们可以想一想,一个程序的出口是什么呢?无非就是这个程序的最后一步,而汉诺塔的最后一步可以简化为一层汉诺塔问题(即将1个盘子从A杆直接移到C杆上),这样我们也就找到了这个递归的出口,也就是(n<=1)。

但是我们又要怎样趋于这个出口呢?其实这个问题我们早就解决了,递归中的第一个参数(n-1)在递归多次进行之下不就会趋于这个出口,所以我们在思考递归函数的参数时十分重要,这就要我们多多练习与函数递归有关的习题来培养一种思维能力(小编的思维能力也很差,我们一起加油)。

由上述分析,我们就可以得到这个汉诺塔函数的相关代码04d9d12dc6b543318c58170b5e94cfd6.png

 79dcf852771741aaa608957a0407042c.png

 图示分析递归实现的过程:

注:图是在纸上画的,我已经尽量保证清晰度以及完整的过程了,希望大家能认真分析一下,如果觉得不方便看,我建议可以抄写一份在自己的纸上慢慢分析。(图上的小记号要注意哈)

提醒一下哈,下三张图表示了三层汉诺塔的六次传参以及五次递归,其中的大写数字(一,二,三等等)是各个传参过程具体分析,而不同张纸上相同数字表示的是同一个函数(主要是我觉得要把相关性强的部分放在一起,导致了一些重复函数在不同的纸上,大家要分清楚)。

5e2f35e5fb0640f9ab5dd3a824f2b455.jpg

41ee141523894723b07d6db2f5eda8e9.jpg

dad392683098419fb7a8e96e98b07915.jpg

为了各位能更好的理解,我会将图示简要分析一下。

细品:

我在图中汉诺塔函数的各个参数上标明了一些小写字母(x,y,z)作为识别标志。将起始过程的A柱标记为x,B柱标记为y,C柱标记为z,我们可以将传参过程中参数的变化转换成标记字母的变化以便观察。
汉诺塔问题的递归分析其实并不难,主要是我们要区分与函数参数以及函数在传参过程中对应参数分别表示什么。(即图中x,y,z在传参过程的变化)

在此我要说明一下:在函数内部调用参数时,是对应字符对应相关参数,而函数传递参数时,则是对应参数位置对应相关参数。

8db378bad4634f95ba46dfbf87a0cbc0.jpg

 再次强调图中x,y,z是我为了分析而规定的,实际并不存在,真正过程对应的还是柱子的标号(A,B,C),希望各位好好区分,好好理解一下。

5. 整体代码及显示效果

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void Move(char x, char y)
{printf("%c --> %c\n", x, y);
}
void HNtower(int a, char A, char B, char C)//汉诺塔函数实施主体,A为初始柱,B为经由柱,C为目的柱
{if (a == 1){Move(A, C);}else{HNtower(a - 1, A, C, B);//第一个递归式Move(A, C);HNtower(a - 1, B, A, C);//第二个递归式}
}
int MoveNum(int a)
{if (a == 1)return 1;elsereturn 2 * MoveNum(a - 1) + 1;//为了对应递归主题,用递归式表示
}
int main()
{int a = 0;printf("请输入你选择的层数:>");scanf("%d", &a);int Num = MoveNum(a);printf("%d层需要移动%d步\n", a, Num);printf("具体过程如下\n");HNtower(a, 'A', 'B', 'C');//进入递归函数return 0;
}

 整个汉诺塔问题就讲解到这里了,希望大家可以好好理解一下,也可以在评论区给我一些建议,谢谢各位光顾,万分感谢。

 6. 寄语

这篇文章小编还是花了一些时间的,希望大家可以好好思考一下,特别是分析清楚其中的递归过程(文章中三张图),希望我的分享可以给各位带来一些帮助吧。那这次的分享到此结束了,请大家好好期待一下小编的下一篇文章吧。

小小宣传:如果各位觉得这篇文章对你有些帮助或是有可学可取之处,还望可以分享给身边其他人,谢谢喽,各位,拜拜 ,下回再见!


http://chatgpt.dhexx.cn/article/lpuKwuK0.shtml

相关文章

关于汉诺塔问题

首先&#xff0c;我们要了解什么是汉诺塔问题。 汉诺塔问题源于古印度的一种游戏&#xff0c;而这种游戏是指在一块铜板装置上&#xff0c;有三根杆(编号A、B、C)&#xff0c;在A杆自下而上、由大到小按顺序放置64个金盘。而我们游戏的目标则是&#xff1a;把A杆上的金盘全部移…

【C语言】汉诺塔问题的解决办法(附图)

1.游戏规则 汉诺塔(Hanoi)游戏是在一块铜板装置上&#xff0c;有三根杆(编号A、B、C)&#xff0c;在A杆自下而上、由大到小按顺序放置64个盘子。游戏的目标&#xff1a;把A杆上的盘子全部移到C杆上&#xff0c;并仍保持原有顺序叠好。操作规则&#xff1a;每次只能移动一个盘子…

Python解决汉诺塔问题

问题引入 汉诺塔问题源于印度一个古老传说。相传大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定&#xff0c;任何时候&#xff0c;在小…

汉诺塔问题(C语言实现)

前言 一、汉诺塔圆盘的移动步数 二、汉诺塔圆盘移动步骤 总结 前言 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序…

Java|汉诺塔问题详解

文章目录 汉诺塔问题&#xff1a;编程要求&#xff1a;解题过程&#xff1a;代码实现&#xff1a;总结 汉诺塔问题&#xff1a; 相传在古印度圣庙中&#xff0c;有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上&#xff0c;有三根杆(编号A、B、C)&#xff0c;在A杆…

C++解决汉诺塔问题

Description 汉诺塔&#xff08;又称河内塔&#xff09;问题是印度的一个古老的传说。开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒A、B和C&#xff0c;A上面套着 n n n个圆的金片&#xff0c;最大的一个在底下&#xff0c;其余一个比一个小&#xff0c;依次叠上去&…

汉诺塔问题超级详解

汉诺塔 汉诺塔问题图解代码 汉诺塔问题 1&#xff0c;我们为了后期方便讲解首先进行一个简单的命名—— 起始柱&#xff1a;1&#xff1b; 过度柱&#xff1a; 2&#xff1b; 目标住&#xff1a;3&#xff1b; 2&#xff0c;由于汉诺塔问题是一个明显的递归问题&#xff0c;所以…

汉诺塔问题解析(C语言)

文章目录 背景一、汉诺塔和递归二、代码实现总结 背景 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄…

python实现汉诺塔问题

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞n片黄金圆盘。大梵天命令婆罗门把圆盘从下自上开始、按大小顺序重新摆放在另一根柱子上。并且规定&#xff0c;小圆盘上不能放…

Python实现 — — 汉诺塔问题

我们今天来看一个很有意思的实例&#xff0c;叫做汉诺塔问题。 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着…

汉诺塔问题(Python实现)

前言 1.先谈一下什么是递归&#xff1f; 我自己的理解就是&#xff1a;将自身的问题不断减小规模&#xff0c;直到减小到无法减小为止。&#xff08;到达递归结束条件&#xff09;然后从小问题开始解决&#xff0c;小问题逐个解决之后&#xff0c;大问题也就迎刃而解了&#…

汉诺塔问题详解(C语言)

文章目录 前言1. 导入汉诺塔问题2. 预备知识3. 分析问题4. 编程解决问题 前言 汉诺塔问题是一个古典的数学问题&#xff0c;本文主要和大家一起用c语言解决汉诺塔问题。 1. 导入汉诺塔问题 相传在古印度圣庙中&#xff0c;有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜…

汉诺塔问题——递归算法

一、问题描述 汉诺塔问题是一个经典的问题。汉诺塔&#xff08;Hanoi Tower&#xff09;&#xff0c;又称河内塔&#xff0c;源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把…

汉诺塔问题详解

目录 一、汉诺塔问题 二、汉诺塔问题思路 三、图示化思路 1、汉诺塔一个盘子 2、汉诺塔两个盘子 3、汉诺塔三个盘子 4、想法 四、代码的实现 一、汉诺塔问题 汉诺塔问题是一个经典的问题。汉诺塔&#xff08;Hanoi Tower&#xff09;&#xff0c;又称河内塔&#xff0c;源…

c语言汉诺塔问题详解

一、前言 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按…

图解汉诺塔问题(递归求解)

汉诺塔&#xff1a;汉诺塔(Tower of Hanoi)源于印度传说中&#xff0c;大梵天创造世界时造了三根金钢石柱子&#xff0c;其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定&#xff0c;在小圆盘上不能放大圆…

汉诺塔(Hanoi)问题归纳总结

一.汉诺塔问题及其递归算法 1.问题阐述 经典汉诺塔&#xff1a; 外文算法书对汉诺塔问题的描述&#xff1a; 2.算法步骤 三阶汉诺塔问题解题步骤 共需7步。 四阶汉诺塔问题解题步骤 共需15步 五阶汉诺塔问题解题步骤 可以清晰的看出分治思想以及递归过程 算法采用了分治的…

汉诺塔问题(Hanoi)

汉诺塔问题&#xff0c;是心理学实验研究常用的任务之一。该问题的主要材料包括三根高度相同的柱子和一些大小及颜色不同的圆盘&#xff0c;三根柱子分别为起始柱A、辅助柱B及目标柱C。 相传在古印度圣庙中&#xff0c;有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置…

经典递归算法——汉诺塔问题

一、问题背景简介 相传在古印度圣庙中&#xff0c;有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上&#xff0c;有三根杆(编号A、B、C)&#xff0c;在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标&#xff1a;把A杆上的金盘全部移到C杆上&#xff…

【C语言】递归详解汉诺塔问题

文章目录 前言汉诺塔移动图解汉诺塔移动次数汉诺塔的打印结语 如果无聊的话&#xff0c;就来逛逛 我的博客栈 吧! &#x1f339; 前言 汉诺塔&#xff0c;是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小…