【汉诺塔】经典递归问题(Java实现)图文并茂讲解

简介: 【汉诺塔】经典递归问题(Java实现)图文并茂讲解


1. 什么是汉诺塔

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

2. 问题分析

首先我们假设三根柱子为A(起始柱子),B(中转柱子),C(结束柱子);有N个圆盘。

  1. N = 1时,就只需要移动1次,即A->C

  1. N = 2时,就需要移动是3次:即A->B A->CB->C

  2. N = 3,就需要移动7次,A->CA->BC->BA->CB->AB->CA->C

以此类推:移动次数 = 2 ^ 圆盘个数 - 1

所以若有64个圆盘那将会移动 2 ^ 64 - 1次(即:18,446,744,073,709,551,615‬次),若每次移动需要1s时间,则需要将近5849亿年的时间才能够做到。可见大梵天有多恨婆罗门,这绝对是在坑人啊!!

综上我们可以将问题分解为以下三个步骤:

  1. 将A柱上的n-1个盘子移动到B柱上
  2. 将A柱上剩下的一个盘子移动到C柱上。
  3. 将B柱上的n-1个盘子移动到C柱上。

通过递归地执行这三个步骤,我们最终可以实现将所有盘子从A柱移动到C柱的目标。

【注意事项】

  1. 递归的终止条件:当只有一个盘子时,可以直接将其从A柱移动到C柱,此时递归终止。
  2. 递归的分解:将问题分解为三个步骤,每次递归调用都是为了完成这三个步骤中的一个。
  3. 递归的回溯:在完成一个递归调用后,需要将问题状态恢复到递归调用前的状态,以便进行下一个递归调用。
  4. 递归的效率:汉诺塔问题的递归解法时间复杂度为O(2^n),其中n表示盘子的数量。因此,当盘子数量较大时,递归解法的时间复杂度会非常高。

动画演示:

代码:

public class Test6 {
    public static void main(String[] args) {
        hanoi(3, 'A', 'B','C');
    }
    
     /**
     * 将盘子从pos1移动到pos2
     * @param pos1 起始柱子
     * @param pos2 结束柱子
     */
    public static void move(char pos1, char pos2){
        System.out.print(pos1 + "->" + pos2 + " ");
    }
    /**
     *
     * @param n 盘子个数
     * @param pos1 起始柱子
     * @param pos2 中转柱子
     * @param pos3 目标柱子
     */
    public static void hanoi(int n, char pos1, char pos2, char pos3){
        if (n == 1){
            move(pos1, pos3);
            return;
        } else{
            hanoi(n-1, pos1, pos3, pos2);
          move(pos1, pos3);
          hanoi(n-1, pos2, pos1, pos3);
        }
    }
}

运行结果:

相关文章
|
6天前
|
Java
java中递归实例
java中递归实例
19 0
|
6天前
|
Java C语言
详解java方法与递归
详解java方法与递归
13 3
|
6天前
|
自然语言处理 Java 编译器
【Java探索之旅】方法重载 递归
【Java探索之旅】方法重载 递归
11 0
|
6天前
|
SQL Java 关系型数据库
java 递归返回树形组织结构(附带树形菜单的搜索)
java 递归返回树形组织结构(附带树形菜单的搜索)
19 0
|
6天前
|
算法 Java
Java必刷入门递归题×5(内附详细递归解析图)
Java必刷入门递归题×5(内附详细递归解析图)
36 1
C4.
|
6天前
|
机器学习/深度学习 存储 搜索推荐
Java的递归
Java的递归
C4.
9 0
|
6天前
|
机器学习/深度学习 Java
【详识JAVA语言】递归
【详识JAVA语言】递归
15 0
|
算法 Java
Java数据结构和算法——汉诺塔问题
package com.tiantian.algorithms; /** * _|_1 | | * __|__2 | | * ___|___3 | | (1).把A上的4个木块移动到C上。
802 0
|
4天前
|
Java 测试技术
Java多线程的一些基本例子
【5月更文挑战第17天】Java多线程允许并发执行任务。示例1展示创建并启动两个`MyThread`对象,各自独立打印"Hello World"。示例2的`CounterExample`中,两个线程(IncrementThread和DecrementThread)同步地增加和减少共享计数器,确保最终计数为零。这些例子展示了Java线程的基本用法,包括线程同步,还有如Executor框架和线程池等更复杂的用例。
11 0