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

Java实现汉诺塔问题

什么是汉诺塔问题

有三根柱子 A B C,其中A柱上有n个大小不同的圆盘,按照大的在下,小的在上的顺序,将n个圆盘从A柱移动到C柱上,每次只能移动一个圆盘,移动过程中可以借助B柱作为中转。

【A表示起始柱子,B表示中转柱子,C表示目标柱子】

递归分析

如果只有1个盘子:A->C(直接将这个盘子从起始柱子A移到目标柱子C)

如果有2个盘子:A->B,A->C,B->C(先将小盘子从A移动到B,然后将大盘子从A移到C,最后将小盘子从B移到C,这样所有盘子就按指定的顺序在C柱子上)

如果有3个盘子:A->C,A->B,C->B,A->C,B->A,B->C,A->C(先将小盘子从A移到C,将中盘子从A移到B,然后将小盘子从C移到B,此时小、中盘就都在B柱子上,然后再将大盘子从A移到C,接着再将小盘子从B移到A,将中盘子从B移到C,最后将小盘子从A移到C,这样就将3个盘子按指定的顺序放到了目标柱子C)

我们要用递归来解决这个问题:

首先创建变量 start表示起始柱子'A'   helper表示中转柱子'B'   end表示目标柱子'C'   n表示盘子数量

通过上述的分析,我们知道除了最下层的大盘子外,其余的盘子都是经过中转柱子B再移到目标柱子C的,即我们需要将n-1个盘子先移到B上后,将大盘子移到C上,此时的大盘子C已经成功移到了目标柱子C上,就剩下除了大盘子外的盘子(小、中盘子们),那么此时的最下面的盘子就变成了新的大盘子,它们所在的B柱子就变成了新的起始柱子,将n-1个盘子先通过新的中转柱子A移到C上,最后将大盘子移到C上;重复这个操作,每次将除了大盘子(会变化,每次将一个大盘子移到C上后,在最下面的盘子就变成新的大盘子)外的n-1个盘子先移到中转柱子(会变化)上后,将大盘子移到C上,直到所有的盘子都按指定的顺序(大的在下,小的在上)在目标盘子C上。

注意:在每次移动的过程中,起始柱子和中转柱子是会随着变化的

代码说明

核心方法:

hanio(n , start , end , heiper):递归求解汉诺塔问题

参数说明:

  • n:要移动的盘子数量
  • start:起始柱子,字符'A'
  • end:目标柱子,字符'C'
  • helper:中转柱子,字符'B'

递归逻辑:

  1. 当只有一个盘子时(递归基),直接移动
  2. 当有多个盘子时:
  •         先将上面n-1个盘子移到中转柱
  •         移动最底层的盘子到目标柱
  •         最后将n-1个盘子从中转柱移到目标柱

完整代码

public class Hanio{public static void main(String[] args){int n = 3;//3个盘子hanio(n,'A','C','B');}public static void hanio(int n,char start,char end,char helper){//只有1个盘子if(n == 1){System.out.println("移动盘子1从" + start + "->" + end);return;}//1.将上面n-1个盘子移到中转柱Bhanio(n-1,start,helper,end);//2.移动最底层的盘子到目标柱子C    System.out.println("移动盘子" + n + "从" + start + "->" + end);//3.将n-1个盘子从中转柱B移到目标柱Chanio(n-1,helper,end,start);}
}

图解递归过程(n=3为例):

初始状态:
A: [3,2,1]   B: [ ]   C: [ ]

1. 移动上面2个盘子到B柱(递归调用):
- 移动1号盘 A→C
- 移动2号盘 A→B
- 移动1号盘 C→B
此时:A: [3]   B: [2,1]   C: [ ]

2. 移动最底层的3号盘:A→C
此时:A: [ ]   B: [2,1]   C: [3]

3. 移动B柱的2个盘子到C柱(递归调用):
- 移动1号盘 B→A
- 移动2号盘 B→C
- 移动1号盘 A→C
此时:A: [ ]   B: [ ]   C: [3,2,1]

更详细版本(展开递归调用):

hanoi(3, A, C, B)
├── hanoi(2, A, B, C)
│   ├── hanoi(1, A, C, B) → 移动1: A→C
│   ├── 移动2: A→B
│   └── hanoi(1, C, B, A) → 移动1: C→B
├── 移动3: A→C
└── hanoi(2, B, C, A)
├── hanoi(1, B, A, C) → 移动1: B→A
├── 移动2: B→C
└── hanoi(1, A, C, B) → 移动1: A→C

如果这里还是不太懂到底如何递归,请往下看代码版的递归图解:

看这个运行结果和我们上面分析的3个盘子的走向一致

(盘子1,2,3指的就是小、中、大盘子的意思)

http://www.dtcms.com/a/334777.html

相关文章:

  • AI Agents 2025年十大战略科技趋势
  • 【嵌入式C语言】六
  • .net印刷线路板进销存PCB材料ERP财务软件库存贸易生产企业管理系统
  • mit6.824 2024spring Lab1 MapReduce
  • 衡石使用指南嵌入式场景实践之仪表盘嵌入
  • 3 统一建模语言(UML)(上)
  • 力扣 hot100 Day75
  • 动手学深度学习(pytorch版):第三章节—线性神经网络(6) softmax回归的从零开始实现
  • 基于深度学习的老照片修复系统
  • 嵌入式硬件篇---电源电路
  • SpringBoot自动配置原理(二)
  • 智能客服、AI工作流、语音、聊天模板
  • MySQL的下载安装(MSI和ZIP版本都有)
  • 【Kubernetes系列】Kubernetes 中 Pod 层参数与 Deployment 层 Env 参数的区别与级别分析
  • WSL中占用磁盘空间大问题解决
  • 自适应阈值二值化参数详解 ,计算机视觉,图片处理 邻域大小 调整常数(C=3)和可视化调节参数的应用程序
  • 区块链技术原理(14)-以太坊数据结构
  • ubuntu更新chrome版本
  • 我的世界Java版1.21.4的Fabric模组开发教程(十九)自定义生物群系
  • 力扣(LeetCode) ——622. 设计循环队列(C语言)
  • 《C语言程序设计》笔记p10
  • 如何拿捏unittest自动化测试框架?
  • 代码随想录算法训练营四十三天|图论part01
  • 同创物流学习记录2·电车
  • 【手撕JAVA多线程】1.从设计初衷去看JAVA的线程操作
  • 【C++】STL 容器—list 底层剖析
  • Java应届生求职八股(5)---并发编程篇
  • JCTools 无锁并发队列基础:ConcurrentCircularArrayQueue
  • 【论文阅读笔记】--Eurosys--HCache
  • 安全审计-firewall防火墙