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

【C语言】递归详解汉诺塔问题汉诺塔 是一个源于印度古老传说的益智玩具 大梵天创造世界的时候做了三根金刚石柱子 在一根柱子上从下往上按照大小顺序摞着 64 片黄金圆盘 大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上 并且规定 在小圆盘上不能放大圆盘 在三根柱子之间一次只能移动一个圆盘 当把 64 片圆盘从第一根石柱移动到第三根石柱时 这个世界就会毁灭 而婆罗门移动圆盘需要用多长时间呢 通过平常的方法是很难计算的 今天我们就利用递归的思想来计算一下汉诺塔的移动次数和汉诺塔的移动步骤

前言

汉诺塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。当把64片圆盘从第一根石柱移动到第三根石柱时,这个世界就会毁灭。

而婆罗门移动圆盘需要用多长时间呢?通过平常的方法是很难计算的。

汉诺塔移动图解

汉诺塔移动的规律为一次只能移动一个圆盘,并且小盘要在大盘的上方,假设在A柱有n个圆盘,我们先要把n-1个圆盘从A柱移动到B柱,再把第n个圆盘移动到C柱,最后把n-1个圆盘移动到C柱。

image-20220706105031319

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

汉诺塔移动次数

利用穷举的办法,对于汉诺塔的移动次数进行计算:

阶数 次数 规律
1 1 2^1-1
2 3 2^2-1
3 7 2^3-1
4 15 2^4-1
2^n-1

对于n阶汉诺塔的移动次数:

  • 步骤1所含步数就是n-1个圆盘移动所需的次数,我们可以将其步数看做f(n-1)。
  • 步骤2所含步数为1。
  • 步骤3所含步数与步骤1相似,我们也将其步数看做f(n-1)。

再观察表格中汉诺塔的移动次数,对于一阶汉诺塔移动次数就为1,对于其他的阶数则为前一阶汉诺塔移动次数 + 1 + 前一阶汉诺塔移动次数。

不难得出递推表达式:f(n-1) + 1 + f(n-1) = 2 * f(n - 1) + 1

移动步骤符合递归思想,代码展示:

#include 
     int hanoi_step(int n) { 
    if(n<=1) return 1; else return 2*hanoi_step(n-1)+1; } int main() { 
    int n = 0; scanf("%d",&n); int ret = hanoi_step(n); printf("%d\n",ret); return 0; } 

运行结果:

image-20220706115426701

汉诺塔的打印

这里的打印指的是打印汉诺塔移动的步骤。

我们可以先尝试写出1-4阶汉诺塔的移动步骤:

阶数 步骤
1 A->C
2 A->B,A->C,B->C
3 A->C,A->B,C->B,A->C,B->A,B->C,A->C
4 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

我们观察移动步骤,发现只有一个圆盘时移动步骤为A->C;两个圆盘时,为A->B,A->C,B->C。

那么对于n阶汉诺塔呢,我们对其进行推演:

  • 把n-1个圆盘从A移动到B
  • 把第n个圆盘从A移动到C
  • 把n-1个圆盘从B移动到C

那n-1个圆盘如何从A移动到B呢?

  • 把n-2个圆盘从A移动到C
  • 把第n-1个圆盘从A移动到B
  • 把n-2个圆盘从C移动到B

同样的,对于把n-1个圆盘从B移动到C,也可以推测出来:

  • 把n-2个圆盘从B移动到A
  • 把第n-1个圆盘从B移动到C
  • 把n-2个圆盘从A移动到C

通过这些推演我们发现,汉诺塔的移动可以通过递归展开,那么以上推演步骤,我们可以将其作为递归的步骤。

#include 
     void hanoi_move(int n,char A,char B,char C) { 
    if(1==n) { 
    printf("%c->%c\n",A,C); } else { 
    hanoi_move(n-1,A,C,B);//将n-1个圆盘从A移动到B printf("%c->%c\n",A,C);//将第n个圆盘从A柱移动到C柱 hanoi_move(n-1,B,A,C);//将n-1个圆盘从B柱移动到C柱 } } int main() { 
    int n = 0; scanf("%d",&n); hanoi_move(n,'A','B','C'); return 0; } 

运行结果:

image-20220706144428116

结语

了解了汉诺塔的移动步数和过程,我们也可以对64片黄金圆盘移动完需要的时间做一个估算,将每次移动看作一秒,那么时间为:2 ^ 64 – 1 = 18,446,744,073,709,551,615秒,换算成年数,约为5800亿年。

按照这个进度,到时候世界毁灭也是有可能的,只是可怜了“悲惨的婆罗门”需要移动这些圆盘(doge)。

以上就是C语言递归求解汉诺塔的全部内容,如果觉得anduin写的还不错的话,还请一键三连!

我是anduin,一名C语言初学者,我们下期见!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228021.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午8:00
下一篇 2026年3月16日 下午8:00


相关推荐

  • python数据清洗补齐_我的世界fill填充上半砖

    python数据清洗补齐_我的世界fill填充上半砖缺失数据比较多的情况下,可以直接滤除,缺失数据比较少时,对数据进行填充就很有必要了。数据填充函数fillna()默认参数如下:fillna(self,value=None,method=None,axis=None,inplace=False,limit=None,downcast=None,**kwargs)importnumpyasnpfromnumpy…

    2022年8月12日
    6
  • 计算机二级考试python怎么考_计算机二级python难度

    计算机二级考试python怎么考_计算机二级python难度2020.09.26更新:今天的二级python最后一个大题考试内容(部分),没考试的同学大家还可以最后挣扎一下。==========================================最新消息:2020年9月(第58次)全国计算机等级考试定于9月26日至29日举行。大家加油鸭!2020.8.15更新:==========2020.1.8更新:有同学问我的公共基础那10分是怎么拿到的,…

    2025年9月25日
    7
  • 惠普电脑有电脑管家吗_电脑管家检测硬件就蓝屏

    惠普电脑有电脑管家吗_电脑管家检测硬件就蓝屏据海外媒体WindowsLatest的报道,大量的Windows10用户的设备最近频繁出现蓝屏,多家硬件设备厂商均中招。联想电脑管家安全团队已证实暂不涉及联想设备的国内用户。同时提醒广大国内用户,暂停近期微软发布的任何更新业务(包括暂停通过Vantage应用程序进行BIOS更新),等待微软官方给出修复补丁。据悉该蓝屏问题是由于近期的一次更新造成,蓝屏(BSOD)错误将会阻止windows10设备的…

    2022年8月13日
    14
  • pycharm激活码2021年6月-激活码分享

    (pycharm激活码2021年6月)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlMLZPB5EL5Q-eyJsaWNlbnNlSWQi…

    2022年3月21日
    169
  • 跟风养龙虾(OpenClaw)到底安不安全?普通人值得装吗?

    跟风养龙虾(OpenClaw)到底安不安全?普通人值得装吗?

    2026年3月13日
    2
  • java写helloworld_Java编写的第一个程序:HelloWorld

    java写helloworld_Java编写的第一个程序:HelloWorld原理:Java文件需要编译后才能运行,编译命令为javacHelloWorld.java(使用javac.exe命令),编译之后会出现以.class结尾的字节码文件(HelloWorld.class)。运行的是字节码文件,运行命令为javaHelloWorld在桌面上创建一个code文件夹,在code文件夹中创建一个HelloWorld.java文件1、编写代码在HelloWorld.jav…

    2022年7月9日
    29

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号