算法——用C语言解答汉诺塔问题

C语言实现汉诺塔问题【图解和演示】 本文将从汉诺塔问题的背景、过程原理,再到C语言代码来解释汉诺塔问题 阅读详情

汉诺塔相信很多人小时候都玩过这样的游戏,这是源于印度的古老传说,大家可千万不要小看这个游戏,里面体现了古人的大智慧,在这里我们能学到最直观的演示方法,本篇主要是针对汉诺塔的问题进行分析和代码展示。

一、前言

汉诺塔,又称河内塔,是一个益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

汉诺塔问题

二、解题思路

思路很简单:有三根相邻的柱子,从左到右分别为:托盘A、托盘B、托盘C;

托盘A按照“从下到上、从大到小”叠放着3个不同大小的盘子;

汉诺塔问题

移动步骤 

第一步:将盘子1从托盘A移动至托盘C

汉诺塔问题

第二步:将盘子2从托盘A移动至托盘B

汉诺塔问题

第三步:将盘子1从托盘C移动至托盘B

汉诺塔问题

第四步:将盘子3从托盘A移动至托盘C

汉诺塔问题

第五步:将盘子1从托盘B移动至托盘A

汉诺塔问题

第六步:将盘子2从托盘B移动至托盘C

汉诺塔问题

第七步:将盘子1从托盘A移动至托盘C

汉诺塔问题

动图演示

0b795385c68d43a88fd535038da4b29a.gif

是不是很简单?

我们从上面移动的过程中,可以看到,托盘B始终作为一个过渡的存在,并且可以把它想象成中转柱;

那么我们就可以这样理解:

托盘A:起始柱A;

托盘B:中转柱B;

托盘C:目标柱C

三、代码实现

递归思想

在解决汉诺塔问题之前,我们先来了解一下递归的思想。递归是一种强大的编程技巧,它允许函数调用自身,就像一个神奇的魔法,能把一个复杂的大问题层层转化为与原问题相似但规模更小的问题,直至问题小到可以直接解决 。就好比剥洋葱,我们每次都去掉一层,不断重复这个过程,直到只剩下最核心的部分。例如,计算阶乘是一个典型的递归应用。阶乘的定义为:n! = n * (n - 1) * (n - 2) *... * 1 。用递归的方式来实现,就是先定义 0! 和 1! 为 1(这是递归的终止条件),然后对于 n > 1 的情况,n! 可以通过调用 (n - 1)! 来计算,即 n! = n * (n - 1)! 。

不过,递归并非无拘无束,它需要满足两个关键条件:

  1. 终止条件:必须有一个明确的终止条件,当满足这个条件时,递归调用就会停止,避免陷入无限循环。例如在计算阶乘时,当 n 为 0 或 1 时,就直接返回 1,不再继续递归。
  1. 递归关系:能够将大问题分解为小问题,并且小问题的解决方式与大问题相同,只是规模更小。比如在计算 n! 时,通过将其转化为计算 (n - 1)! ,问题的本质没有改变,只是数据规模从 n 减小到了 n - 1 。

C语言代码

#include <stdio.h>
 
void move(int n, char pos1, char pos3)
{
    //打印移动的过程
    // 1代表上面最小的盘子
    // 2代表中间位置的盘子
    // 3代表下面最大的盘子
    printf("盘子%d: 从 %c柱 移动到 %c柱\n", n, pos1, pos3);
 
}
 
void Hanoi(int n, char pos1, char pos2, char pos3)
{
    //如果是1个盘子,直接从起始柱A移动到目标柱C
    if (n == 1) 
    {
        move(n, pos1, pos3);
    }
    else
    {
        //如果盘子大于1个,需要把n-1个盘子,从起始柱pos1,通过目标柱pos3,移动到中转柱pos2
        Hanoi(n-1, pos1, pos3, pos2); 
 
        //此时pos1上的n-1个盘子全部移动pos2上去了,那么可以直接把pos1上剩下的1个盘子,直接移动到pos3上
        move(n, pos1, pos3);
 
        //把pos2剩下的n-1个盘子,通过中转位置pos1,移动到目标位置pos3
        Hanoi(n-1, pos2, pos1, pos3);
    }
}
 
int main()
{
    //盘子个数
    int n = 3;
 
    //起始柱A
    char pos1 = 'A';
 
    //中转柱B
    char pos2 = 'B';
 
    //目标柱C
    char pos3 = 'C';
 
    printf("移动%d个盘子的步骤如下↓\n", n);
 
    //汉诺塔函数
    Hanoi(n, pos1, pos2, pos3);
 
    return 0;
}

移动三个盘子步骤 

移动3个盘子的步骤如下↓
盘子1: 从 A柱 移动到 C柱
盘子2: 从 A柱 移动到 B柱
盘子1: 从 C柱 移动到 B柱
盘子3: 从 A柱 移动到 C柱
盘子1: 从 B柱 移动到 A柱
盘子2: 从 B柱 移动到 C柱
盘子1: 从 A柱 移动到 C柱

移动四个盘子步骤


盘子1: 从 A柱 移动到 B柱
盘子2: 从 A柱 移动到 C柱
盘子1: 从 B柱 移动到 C柱
盘子3: 从 A柱 移动到 B柱
盘子1: 从 C柱 移动到 A柱
盘子2: 从 C柱 移动到 B柱
盘子1: 从 A柱 移动到 B柱
盘子4: 从 A柱 移动到 C柱
盘子1: 从 B柱 移动到 C柱
盘子2: 从 B柱 移动到 A柱
盘子1: 从 C柱 移动到 A柱
盘子3: 从 B柱 移动到 C柱
盘子1: 从 A柱 移动到 B柱
盘子2: 从 A柱 移动到 C柱
盘子1: 从 B柱 移动到 C柱

四、算法效率的考量

 

(一)时间复杂度

汉诺塔问题递归算法的时间复杂度为\(O(2^n)\)。这是因为在递归过程中,每次递归调用都会产生两个子问题,即移动\(n-1\)个圆盘的操作会被执行两次。随着递归层数的增加,子问题的数量呈指数级增长。具体来说,对于\(n\)个圆盘,需要执行\(2^n - 1\)次移动操作。当\(n\)较小时,\(2^n\)的增长速度可能不太明显,但当\(n\)逐渐增大时,时间复杂度的增长将变得极为迅速,导致计算量呈指数级上升。例如,当\(n = 10\)时,移动次数为\(2^{10}-1 = 1023\)次;当\(n = 20\)时,移动次数则高达\(2^{20}-1 = 1048575\)次 ,这使得解决大规模汉诺塔问题的时间成本变得非常高昂。

(二)空间复杂度

空间复杂度主要取决于递归调用的深度。在汉诺塔问题中,递归调用的深度与圆盘的数量\(n\)相等。因为在每一层递归中,系统需要为函数调用分配栈空间,用于保存函数的参数、局部变量和返回地址等信息。随着递归的进行,栈空间不断被占用,直到达到最大递归深度。当递归返回时,栈空间逐渐被释放。由于递归调用的最大深度为\(n\),所以汉诺塔问题的空间复杂度为\(O(n)\)。尽管空间复杂度的增长相对较为线性,但在处理非常大的\(n\)值时,仍然可能会面临栈溢出的风险,这也是在实际应用中需要考虑的问题之一。

【C语言】汉诺塔问题(图文详解) C语言汉诺塔及详细图文展示 阅读详情

相关推荐

C语言 - 汉诺塔详解(超详细)

文章目录一、前言二、汉诺塔打印步数三、汉诺塔打印步骤 一、前言 一、汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。          A       B       C 二、汉诺塔打印步数   1. /*******************

DanceBit的博客 9万+

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

想要深度了解汉诺塔问题吗??? 快来看这里了保姆式介绍哟!!!

weixin_72868952的博客 1万+

深度学习中 Internal Covariate Shift 问题以及 Batch Normalization 的作用

深度学习中 Internal Covariate Shift 问题以及 Batch Normalization 的作用前言一、Batch Normalization是什么?1.1 Internal Covariate Shift1.2 Internal Covariate Shift 带来的影响1.3 如何减缓 Internal Covariate Shift 问题带来的影响白化(Whitening)白化存在的问题二、Batch Normalization2.1 传统 Normalization2.2 改进

一扣解千愁的博客 4297

汉诺塔问题的时间复杂度

递归算法所有圆盘移动到右边的杆子上,并且每次移动时必须遵守下列两个规则:一次只能移动一个圆盘。不能将大盘放在小盘上面。

kashine的博客 1万+

强化学习-动态规划

动态规划(dynamic programming)是程序设计算法中非常重要的内容,能够高效解决一些经典问题,例如背包问题和最短路径规划。动态规划的基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到目标问题的解。动态规划会保存已解决的子问题的答案,在求解目标问题的过程中,需要这些子问题答案时就可以直接利用,避免重复计算。本章介绍如何用动态规划的思想来求解在马尔可夫决策过程中的最优策略。

qq_45481856的博客 2115

W5500+STM32F103C8T6进行TCP通信(modbus)

一路生花一、w5500资料二、modbus通信三、从机代码四、总结五、参考 一、w5500资料 w5500的资料就放在下面了,单纯的客户端和其他模式上面有教程 https://www.aliyundrive.com/s/enPnnZgNtpE 二、modbus通信 Modbus RTU通信时使用的数据帧结构如下图,而Moubus TCP通信的数据帧和这个稍微不一样,没有crc检验,因为tcp本就是一种可靠传输协议 这里是Modbus TCP数据帧 公共功能码定义 三、从机代码

junseven164的博客 5780

怎么理解汉罗塔问题_C语言汉诺塔问题,不是很理解

//汉诺塔2#include3voidhanoi(intn,chara,charb,charc)//这里代表将a柱子上的盘子借助b柱子移动到c柱子4{if(1==n)//如果是一个盘子直接将a柱子上的盘子移动到c5{6printf("%c...// 汉诺塔2 # include 3 void hanoi ( int n, char a, char b, char c ) //...

weixin_39610722的博客 273

地平线旭日X3派(RDK X3)从开箱到联网:新手避坑指南

本文为地平线旭日X3派(RDK X3)新手提供从开箱到联网的完整避坑指南。详细讲解了硬件识别、系统镜像烧录、串口调试(波特率921600)、有线/无线网络配置以及SSH/VNC远程访问等关键步骤,帮助开发者快速搭建稳定的开发环境,为后续AI应用部署扫清障碍。

weixin_29174385的博客 953

C语言-函数

a[0] < a[1] && a[1] < a[2] && a[2] < a[3] && .... && a[n-2] < a[n-1] n个元素。// sum(4,6) ==> 10 "函数调用表达式" --> 该表达式的值就该函数的返回值。//表示函数结束,带有一个返回值,这个返回值就是表达式的值。// OK 16 // 先会计算出实参的值, 再将实参的值 传递给 形参。a[0] < a[1] && a[1] < a[2] && a[2] < a[3] 4个元素。

m0_69032433的博客 879

微信小程序一键登录和临时code用JWT进行微信用户授权

2、跨域进行调用接口时候,唯一标识UnionID和会话密钥 session_key如果还是用的我自己的,会出现无法调用微信服务器接口,就需要将唯一标识和会话密钥换成前端的,才可以,我自己认为这样很不合理,暂时还没有找到原因。2、能够获取到openId,但是也只能获取到openid,无法获取用户的相关信息,经过查阅官网发现,现在微信那边已经将用户信息加密,需要调用提供的接口进行解密然后获取用户数据,问题原因已经找到解决方法,还未即使更改。1、我这是一台电脑实现的前端调用后端接口,不用考虑跨域的问题。

qq_67653492的博客 5717

生成EtherCAT从站XML图片信息方法

详细介绍了EtherCAT从站XML文件中图片元素的生成方法。

kevin1499的博客 2130

C语言汉诺塔问题的递归算法

C语言汉诺塔问题的递归算法

langchou的博客 1万+

YOLO11改进策略【独家融合改进】| RCSOSA + SPD + WFU

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。WFU模块通过小波变换的频率分解与跨尺度融合机制,解决了传统上采样过程中的混叠和细节丢失问题,实现了高效、高保真的面部细节重建。

Limiiiing的博客 453

C中如何使用递归算法解决汉诺塔问题?

在C语言中,我们可以定义一个递归函数hanoi来解决汉诺塔问题。该函数接收四个参数:盘子数量n,起始柱子from,辅助柱子aux,目标柱子to。// 定义移动函数,用于打印移动操作printf("将盘子从 %c 移动到 %c\n", from, to);// 定义汉诺塔递归函数} else {// 将n-1个盘子从from移动到aux,借助to// 将第n个盘子从from移动到to// 将n-1个盘子从aux移动到to,借助fromint n;printf("请输入盘子的数量: ");

wang15510689957的博客 910

2022年12月机器人技术等级考试试卷(三级实操) 试题解析

2022年12月机器人技术等级考试试卷(三级实操) 试题解析

http://www.cierobot.com 1523

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C语言实现 蓝桥杯 算法提高 汉诺塔

试题 算法提高 汉诺塔                                         &nbs

xyf0209的博客 1078

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

c语言的练习-汉诺塔问题

这篇文章是一位编程初学者分享汉诺塔问题的解决心得。作者通过手绘2-4层金片的移动过程,总结出关键规律:当金片数为偶数时首个金片移到B柱,奇数时移到C柱。文章详细讲解了递归思路,即解决n层问题需先解决n-1层问题,并附上代码实现。作者用通俗易懂的语言和手绘图解,展示了如何将n-1个金片从A柱经C柱移到B柱,再将第n个金片直接移到C柱,最后将n-1个金片从B柱移回C柱的完整过程。虽然自称是新手,但作者通过实践和请教他人,成功理解了汉诺塔问题的递归解法。

2502_94595207的博客 1111

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

汉诺塔问题(详细解答)

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

2303_80341387的博客 709

【算法】分治算法,解决汉诺塔问题

大家好,我是被白菜拱的猪。 一个热爱学习废寝忘食头悬梁锥刺股,痴迷于girl的潇洒从容淡然coding handsome boy。 文章目录一、写在前言二、分治算法(一)内容介绍(二)汉诺塔问题1、思路讲解2、代码实现三、结束语 一、写在前言 数据结构内容大体已经学的差不多,终于迈进了算法的大门,下面将学习几个常见的算法思想,好了闲话不多说,今天让我们走进分治算法的世界。 二、分治算法 (一)内容介绍 分治分治就是分而治之,把一个复杂大的问题分解成一个个小小的问题,然后在去解决这些的小的问题就简单许多了,然

放开这颗白菜让我来 317

汉诺塔c语言程序蓝桥杯,C语言实现 蓝桥杯 算法提高 汉诺塔

试题 算法提高 汉诺塔蓝桥杯试题解答汇总链接资源限制时间限制:1.0s 内存限制:256.0MB问题描述汉诺塔是一个古老的数学问题:有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:每次只能移动一个圆盘;大盘不能叠在小盘上面。提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。问:如何移?最...

weixin_30967451的博客 240

【C语言编程】C语言实现汉诺塔编程!(递归思想)

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

weixin_48994377的博客 940

用C语言实现汉罗塔问题

汉罗塔是什么?汉罗塔算法为什么要这么实现?算法的路径是如何走的?

2301_76599307的博客 1300

c语言递归汉诺塔次数,c语言递归解决汉诺塔参数变化的疑惑

c语言递归解决汉诺塔参数变化的疑惑答案:3信息版本:手机版解决时间 2020-04-05 14:20已解决2020-04-05 10:49#include void main(){void hanoi(int n,char one,char two,char three);int m;printf("input the number of disks:");scanf("%d",&m)...

weixin_29388659的博客 282

汉诺塔C递归算法详细解答

#include"stdio.h" void move(char x,char y) { printf("%c-->%c ",x,y); } void hanoi(int n,char a,char b,char c) { if(n==1) move(a,c); else{ hanoi(n-1,a,c,b);/*将n个盘从one座借助two座,移到three座*/

一念永恒 2332

汉诺塔问题 ——以c语言为例

#include <stdio.h> #include <iostream> using namespace std; //汉诺塔问题:利用递归的思想实现(分治法) void hannoi(int n,char A, char B ,char C){ if(1==n){ cout<<"Move" <<A<<"to"<<C<<endl; return ; } //1.算出n-1个盘子,将其从A移到B ha

immortalize的博客 502

汉诺塔问题递归算法分析

递归实现了某种类型的螺旋状while循环。while循环在循环体每次执行时必须取得某种进展,逐步迫近循环终止条件。 递归函数也是如此,它在每次递归调用后必须越来越接近某种限制条件。当递归函数符合这个限制条件时,它便不在调用自身。递归算法的特点   递归算法是一种直接或者间接地调用自身的算法。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。   递归

644
上一篇: STM32F103C8----外部中断探秘:解锁嵌入式实时响应的关键
下一篇: 算法——数学建模的十大常用算法
夏子曦
夏子曦 优质创作者: 产品设计技术领域 优质创作者: 产品设计技术领域
博客等级 码龄15年 8289粉丝 427原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值