【汉诺塔】经典递归问题(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);
        }
    }
}

运行结果:

相关文章
|
2月前
|
Java
java基础(11)函数重载以及函数递归求和
Java支持函数重载,即在同一个类中可以声明多个同名方法,只要它们的参数类型和个数不同。函数重载与修饰符、返回值无关,但与参数的类型、个数、顺序有关。此外,文中还展示了如何使用递归方法`sum`来计算两个数之间的和,递归的终止条件是当第一个参数大于第二个参数时。
32 1
java基础(11)函数重载以及函数递归求和
|
4月前
|
算法 Java
java使用递归及迭代方式实现前序遍历 中序遍历 后序遍历 以及实现层序遍历
java使用递归及迭代方式实现前序遍历 中序遍历 后序遍历 以及实现层序遍历
86 7
|
5月前
|
Java
java实现斐波那契数列(递归、迭代、流)
java实现斐波那契数列(递归、迭代、流)
|
5月前
|
存储 Java
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
39 0
|
5月前
|
Java 大数据 程序员
老程序员分享:java递归
老程序员分享:java递归
28 0
|
5月前
|
Java
汉诺塔(java)
汉诺塔(java)
|
5月前
|
Java
二分查找-递归(java)
二分查找-递归(java)
|
5月前
|
Java
java使用递归遍历文件目录
java使用递归遍历文件目录
|
算法 Java
Java数据结构和算法——汉诺塔问题
package com.tiantian.algorithms; /** * _|_1 | | * __|__2 | | * ___|___3 | | (1).把A上的4个木块移动到C上。
839 0