当前位置: 首页 > news >正文

【汉诺塔 —— (经典分治递归)】

汉诺塔 —— (经典分治递归)

  • 一.汉诺塔介绍
  • 二.分治算法解决汉诺塔问题
  • 三.汉诺塔问题的代码实现
  • 四.主函数测试展示

一.汉诺塔介绍

汉诺塔问题源自印度一个古老的传说,印度教的“创造之神”梵天创造世界时做了 3 根金刚石柱,其中的一根柱子上按照从小到大的顺序摞着 64 个黄金圆盘。梵天命令一个叫婆罗门的门徒将所有的圆盘移动到另一个柱子上,移动过程中必须遵守以下规则:
每次只能移动柱子最顶端的一个圆盘;
每个柱子上,小圆盘永远要位于大圆盘之上;

图 1 给您展示了包含 3 个圆盘的汉诺塔问题:

在这里插入图片描述

图 1 汉诺塔问题

一根柱子上摞着 3 个不同大小的圆盘,那么在不违反规则的前提下,如何将它们移动到另一个柱子上呢?图 2 给大家提供了一种实现方案:

在这里插入图片描述

图 2 汉诺塔问题的解决方案

汉诺塔问题中,3 个圆盘至少需要移动 7 次,移动 n 的圆盘至少需要操作 2n-1 次。

在汉诺塔问题中,当圆盘个数不大于 3 时,多数人都可以轻松想到移动方案,随着圆盘数量的增多,汉诺塔问题会越来越难。也就是说,圆盘的个数直接决定了汉诺塔问题的难度,解决这样的问题可以尝试用分治算法,将移动多个圆盘的问题分解成多个移动少量圆盘的小问题,这些小问题很容易解决,从而可以找到整个问题的解决方案。

二.分治算法解决汉诺塔问题

为了方便讲解,我们将 3 个柱子分别命名为起始柱、目标柱和辅助柱。实际上,解决汉诺塔问题是有规律可循的:

1) 当起始柱上只有 1 个圆盘时,我们可以很轻易地将它移动到目标柱上;
2) 当起始柱上有 2 个圆盘时,移动过程如下图所示:

在这里插入图片描述

图 3 移动两个圆盘

移动过程是:先将起始柱上的 1 个圆盘移动到辅助柱上,然后将起始柱上遗留的圆盘移动到目标柱上,最后将辅助柱上的圆盘移动到目标柱上。

3) 当起始柱上有 3 个圆盘时,移动过程如图 2 所示,仔细观察会发现,移动过程和 2 个圆盘的情况类似:先将起始柱上的 2 个圆盘移动到辅助柱上,然后将起始柱上遗留的圆盘移动到目标柱上,最后将辅助柱上的圆盘移动到目标柱上。

通过分析以上 3 种情况的移动思路,可以总结出一个规律:对于 n 个圆盘的汉诺塔问题,移动圆盘的过程是:
1.将起始柱上的 n-1 个圆盘移动到辅助柱上;
2.将起始柱上遗留的 1 个圆盘移动到目标柱上;
3.将辅助柱上的所有圆盘移动到目标柱上。

由此,n 个圆盘的汉诺塔问题就简化成了 n-1 个圆盘的汉诺塔问题。按照同样的思路,n-1 个圆盘的汉诺塔问题还可以继续简化,直至简化为移动 3 个甚至更少圆盘的汉诺塔问题。

三.汉诺塔问题的代码实现

//将n个圆盘借助by从from移到to
void hanoi(int n, char from, char to, char by)
{void move(int n, char x, char y);if (n == 1)move(n, from, to);else{hanoi(n - 1, from, by, to);move(n, from, to);hanoi(n - 1, by, to, from);}
}void move(int n, char x, char y)
{printf("第%d个圆盘从%c->%c\n", n, x, y);
}int main() {int n = 0;printf("请输入A柱上圆盘个数:");scanf("%d", &n);//将n个圆盘借助C从A移到Bprintf("移动方法展示:\n");hanoi(n, 'A', 'B', 'C');return 0;
}

四.主函数测试展示

在这里插入图片描述
在这里插入图片描述

http://www.lryc.cn/news/242449.html

相关文章:

  • APP运营常用的ChatGPT通用提示词模板
  • 医学检验(LIS)管理系统源码,LIS源码,云LIS系统源码
  • RabbitMQ 安装(在docker容器中安装)
  • 机器学习入门
  • HarmonyOS ArkTS 保存应用数据(十)
  • 【JavaEE】Spring更简单的存储和获取对象(类注解、方法注解、属性注入、Setter注入、构造方法注入)
  • linux上的通用拍照程序
  • 代码随想录-刷题第七天
  • C# 获取图像、字体等对象大小的数据结构SizeF
  • 「 系统设计 」 为什么要做架构分层?
  • 4:kotlin 方法(Functions)
  • Pycharm run 输出界面控制一行能够输出的元素个数
  • C++初级项目webserver项目流程介绍(2)
  • SIPp mac和debian用法可能略有差别
  • echarts的横向柱状图文字省略,鼠标移入显示内容 vue3
  • laravel8安装多应用多模块(笔记三)
  • Vue组件的几种通信方式
  • golang panic关键词执行原理与代码分析
  • Error running Tomcat8: Address localhost:1099 is already in use 错误解决
  • android studio如何给安卓虚拟机发送短信
  • 立体仓库PLC控制系统子站诊断功能块
  • NFT Insider115:The Sandbox开设元宇宙Diorama快闪店,​YGG Web3 游戏峰会已开幕
  • 【Redis篇】简述Java中操作Redis的方法
  • 深度解读英伟达新一轮对华特供芯片H20、L20、L2的定位
  • 一起学docker系列之九docker运行mysql 碰到的各种坑及解决方法
  • 利用Nginx与php处理方式不同绕过Nginx_host实现SQL注入
  • 分割list 批量插入数据指定条数数据
  • Arduino库之 LedControl 库说明文档
  • Hadoop学习总结(MapReduce的数据去重)
  • ctfshow sql