递归经典例题 --- 汉诺塔(图文详解)
创始人
2024-01-29 16:36:49
0

目录

一、介绍

二、游戏规则

三、玩法简介

四、算法分析

五、代码解析

六、源码

七、递归过程详解


一、介绍

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

                                                                                                                             ---- 摘抄百度

二、游戏规则

把A杆上的盘子全部移到C杆上,并仍保持原有顺序叠好。

操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下小盘在上,操作过程中盘子可以置于A(起始柱)、B(辅助柱)、C(目标柱)任一杆上。 

三、玩法简介

假设有三个盘子,全部都要移动到C(如下图)

 根据汉诺塔的游戏规则,首先需要把3号盘子和2号盘子分别向B和C移动(如下图)

 接着把3号盘子移动到B,再1号盘移动到C,此时最大的盘子已经到C的底部了(如下图) 

 接着把3号盘子移动到A,然后把2号盘子移动到C(如下图)

最后把3号盘子移动到C(如下图),游戏就成功了!

四、算法分析

假设有n个盘子,来分析其规律

①当n = 1时,A只有1个盘子,可以很轻易地将它移动到C上

②当n = 2时,A有2个盘子

其移动过程,先把A中2号盘子移动到B中暂存

 再把A中1号盘子移动到C

 最后把B中2号盘子移动到C

③ 当n = 3时

玩法简介讲过了。

总结:

通过分析以上三种情况的移动思路,小伙伴发现一个规律没有,对于n个盘子的汉诺塔问题,移动圆盘的过程是:

1.都是将起始柱(A)上的n-1(除最大盘子外)个圆盘移动到辅助柱(B)上。  

2.再将起始柱(A)上遗留的(最大盘子)1个圆盘移动到目标柱(C)上。  

3.最后将辅助柱(B)上所有的圆盘移动到目标柱(C)上。        

要解决n层汉诺塔,就必须解决n-1的汉诺塔。由此,n 个圆盘的汉诺塔问题就简化成了 n-1 个圆盘的汉诺塔问题,把一个复杂的问题简单化,这就是递归

五、代码解析

首先写出主函数的内容

#include 
int main()
{int n = 0;//n代表盘子个数//输入盘子的个数scanf("%d", &n);//写出函数Hanno_Tower(n, 'A', 'B', 'C');return 0;
}

根据上面的总结分析

调用函数部分:

当n=1时,直接移动到C(目标柱)就行了

void Hanno_Tower(int n, char A, char B, char C)
{if (n == 1){printf("将编号为%d的盘子从%c柱子移动到%c柱子上\n", n, A, C);}
}

当n>1时,首先要把起始柱(A)上的n-1(除最大盘子外)个圆盘移动到辅助柱(B)上

这时就要再次调用Hanno_Tower函数

void Hanno_Tower(int n, char A, char B, char C)
{if (n == 1){printf("将编号为%d的盘子从%c柱子移动到%c柱子上\n", n, A, C);}else{Hanno_Tower(n - 1, A, C, B);//将n-1个盘子,从A绕过C移动到B}
}

再将起始柱(A)上遗留的(最大盘子)1个圆盘移动到目标柱(C)上

void Hanno_Tower(int n, char A, char B, char C)
{if (n == 1){printf("% c-> % c\n",A, C);}else{Hanno_Tower(n - 1, A, C, B);//将n-1个盘子,从A绕过C移动到Bprintf("将编号为%d的盘子从%c柱子移动到%c柱子上\n", n, A, C);//将起始柱上遗留的1个圆盘移动到目标柱上}
}

最后将辅助柱(B)上所有的圆盘移动到目标柱(C)上。 

void Hanno_Tower(int n, char A, char B, char C)
{if (n == 1){printf("% c-> % c\n",A, C);}else{Hanno_Tower(n - 1, A, C, B);//将n-1个盘子,从A绕过C移动到Bprintf("% c-> % c\n",A, C);//将起始柱上遗留的1个圆盘移动到目标柱上Hanno_Tower(n-1, B, A, C);//把在B中剩余的n-1个盘子,从B绕过A移动到C}
}

六、源码

#include 
void Hanno_Tower(int n, char A, char B, char C)
{if (n == 1){printf("将编号为%d的盘子从%c柱子移动到%c柱子上\n", n, A, C);}else{Hanno_Tower(n - 1, A, C, B);printf("将编号为%d的盘子从%c柱子移动到%c柱子上\n", n, A, C);Hanno_Tower(n - 1, B, A, C);}
}
int main()
{int n = 0;scanf("%d", &n);Hanno_Tower(n, 'A', 'B', 'C');return 0;
}

七、递归过程详解

假设只有2个盘子

n = 1继续调用函数,但这里要注意,图三n = 1时,此时char A存放的是A, char B存放的是C,char C存放的是B,执行if语句,所以首先会先打印“将编号为1的盘子从A柱子移动到B柱子上”

接下来开始回归(红线)

n = 2 ,接下来会在屏幕上打印“将编号为2的盘子从A柱子移动到C柱子上”

最后调用Hanno_Tower(n - 1, B, A, C);接下来继续用图来帮助大家分析

  如图三所示,n = 1,执行if语句,此时char A存放的是B,char B存放的是A,char C存放的是C,所以最后就会打印“将编号为1的盘子从B柱子移动到C柱子上”

所以当n = 2时,程序是否能打印以上结果呢?

 显然符合我们的预期!!

相关内容

热门资讯

年中经济观察丨新业态、新模式、...   今年上半年,服务贸易在我国经济成绩单中表现出色,不仅增长势头良好,更萌生出了新业态、新模式。从数...
LPR报价出炉:1年期和5年期...   中国人民银行授权全国银行间同业拆借中心公布,2025年7月21日贷款市场报价利率(LPR)为:1...
提升人才培养与需求契合度   “菁英班为我提供了直接参与产业实际问题的机会和平台,校企双方老师的帮助使我站在巨人的肩膀上,这是...
活力中国调研行|从这里一窥东北...   许多人脑海中都曾有过一处向往的田园,那里有平畴沃野、绿水青山,那里能安放下日子的暖,生长出产业的...
从中国“链”向世界!链博会定义...   为期5天的第三届中国国际供应链促进博览会落下帷幕  本届链博会亮点,一文速览↓↓↓  全球首展!...
国家防总提升对广东、海南防汛防...   国家防汛抗旱总指挥部20日将针对广东、海南的防汛防台风应急响应提升至三级,维持针对广西的防汛防台...
周知警惕!防范藏在暗处的技术后... 网络安全不仅关乎个人隐私、企业秘密,甚至影响着国家安全。需要警惕的是,一些别有用心的设计或恶意植入的...
各地文旅市场“全面开花” 多重...   央视网消息:需求升级、供给上新。针对暑期旅游旺季,各地也推出了丰富的文旅消费产品,差异化的文旅体...
伊朗同意与欧洲三国举行新一轮谈...   当地时间21日凌晨,总台记者获悉,应欧洲国家要求,伊朗同意与伊核协议中的英、法、德三个欧洲国家代...
俄罗斯萨哈共和国一大巴倾覆 已...   △俄罗斯萨哈共和国检察院公布事故图片  据俄罗斯萨哈(雅库特)共和国内务部当地时间21日通报,当...