X航 2024-07-31 10:19 采纳率: 0%
浏览 5

关于#java#的问题:汉诺塔的输出问题

有个递归问题
按照递归LIFO后进先出的规律,先执行的不应该是最后的栈中的move指令吗,即最大的盘子移动到c。所以输出的第一条应该也是最后的方块移动到c塔呀,这不是反过来了吗。


public class Hanoilmpl {


public static void hanoi(int n, char A, char B, char C) {
    if (n == 1) {
        move(A, C);
    } else {
        hanoi(n - 1, A, C, B);//将n-1个盘子由A经过C移动到B
        move(A, C);             //执行最大盘子n移动
        hanoi(n - 1, B, A, C);//剩下的n-1盘子,由B经过A移动到C
    }
}

private static void move(char A, char C) {//执行最大盘子n的从A-C的移动
    System.out.println("move:" + A + "--->" + C);
}

public static void main(String[] args) {
    System.out.println("移动汉诺塔的步骤:");
    hanoi(3, 'a', 'b', 'c');
}

} 
  • 写回答

1条回答 默认 最新

  • 代码伐木匠 2024-07-31 11:46
    关注

    你提出的关于汉诺塔递归输出的问题很有意义。汉诺塔问题的解决方案确实涉及递归的 LIFO(后进先出)特性。

    汉诺塔问题概述

    汉诺塔问题的解决方案基于递归思想,具体步骤如下:

    1. **将 n-1 个盘子从起始杆 A 移动到辅助杆 B**,借助目标杆 C
    2. **将第 n 个盘子(最大的盘子)从起始杆 A 移动到目标杆 C**。
    3. **将 n-1 个盘子从辅助杆 B 移动到目标杆 C**,借助起始杆 A

    递归的调用顺序

    在递归过程中,调用是按照以下顺序进行的:

    1. 首先执行 hanoi(n-1, A, C, B),这一步会将 n-1 个盘子移动到辅助杆 B,并且在这个过程的最终阶段会执行 move(A, C)
    2. 然后执行 move(A, C),将第 n 个盘子从起始杆 A 移动到目标杆 C
    3. 最后执行 hanoi(n-1, B, A, C),这一步会将 n-1 个盘子从辅助杆 B 移动到目标杆 C

    在递归的调用栈中,最底层的 hanoi(n-1, B, A, C) 会在所有递归调用完成后执行。因此,最初移动 n-1 个盘子的所有步骤在最大盘子移动之后才会完成。

    输出顺序

    所以,递归输出的顺序是符合汉诺塔的移动步骤的:

    1. 先移动 n-1 个盘子:这些步骤在最开始的递归调用中完成,递归调用栈最底层先被执行。
    2. 然后移动最大盘子:这是当前递归层的 move(A, C)
    3. 最后移动 n-1 个盘子:这部分在最后的递归调用中执行,递归调用栈的最上层先被执行。

    示例

    对于 hanoi(3, 'a', 'b', 'c'),输出的顺序是这样的:

    1. **将 2 个盘子从 a 移动到 b**:
      • 将 1 个盘子从 a 移动到 c
      • 将 1 个盘子从 a 移动到 b
      • 将 1 个盘子从 c 移动到 b
    2. 将最大盘子从 a 移动到 c
    3. **将 2 个盘子从 b 移动到 c**:
      • 将 1 个盘子从 b 移动到 a
      • 将 1 个盘子从 b 移动到 c
      • 将 1 个盘子从 a 移动到 c

    实际输出

    你的程序中 System.out.println 会按照递归的调用顺序输出移动步骤,符合汉诺塔的逻辑步骤。你提到的“反过来”可能是因为递归调用在执行 hanoi(n-1) 后,再执行 move,然后再执行 hanoi(n-1) 的顺序,实际输出是按照汉诺塔的解决步骤来进行的。

    总结

    • 递归函数的 LIFO 特性 确保了内层的递归(处理 n-1 个盘子)在外层递归(处理最大盘子)之前完成。
    • 输出顺序 确实是符合汉诺塔的解法步骤。

    所以你看到的输出顺序实际上是正确的,符合汉诺塔问题的解法逻辑。
    你的示例代码本身是正确的,并且展示了汉诺塔问题的递归解法。为了更清楚地展示汉诺塔的解决过程,以下是完善的示例代码,包括了详细的注释以解释每个步骤:

    public class HanoiImpl {
    
        public static void hanoi(int n, char A, char B, char C) {
            // 基本情况:只移动一个盘子
            if (n == 1) {
                move(A, C); // 将盘子从 A 移动到 C
            } else {
                // 递归步骤:将 n-1 个盘子从 A 移动到 B,使用 C 作为辅助杆
                hanoi(n - 1, A, C, B);
                // 将第 n 个盘子从 A 移动到 C
                move(A, C);
                // 将 n-1 个盘子从 B 移动到 C,使用 A 作为辅助杆
                hanoi(n - 1, B, A, C);
            }
        }
    
        // 打印移动盘子的步骤
        private static void move(char A, char C) {
            System.out.println("move: " + A + " ---> " + C);
        }
    
        public static void main(String[] args) {
            int numberOfDisks = 3; // 可以改变盘子的数量来测试不同情况
            System.out.println("移动汉诺塔的步骤:");
            hanoi(numberOfDisks, 'a', 'b', 'c');
        }
    }
    

    示例解释

    1. 基础情况:

      • n == 1 时,只需将盘子从起始杆 A 移动到目标杆 C
    2. 递归步骤:

      • 步骤 1: 将 n-1 个盘子从 A 移动到辅助杆 B,使用目标杆 C 作为辅助。
      • 步骤 2: 将第 n 个盘子从 A 移动到 C
      • 步骤 3: 将 n-1 个盘子从 B 移动到 C,使用起始杆 A 作为辅助。

    输出示例

    假设 numberOfDisks = 3,输出将会是:

    移动汉诺塔的步骤:
    move: a ---> c
    move: a ---> b
    move: c ---> b
    move: a ---> c
    move: b ---> a
    move: b ---> c
    move: a ---> c
    

    解释输出顺序

    1. **将 2 个盘子从 a 移动到 b**:

      • 将 1 个盘子从 a 移动到 c
      • 将 1 个盘子从 a 移动到 b
      • 将 1 个盘子从 c 移动到 b
    2. 将最大盘子从 a 移动到 c

    3. **将 2 个盘子从 b 移动到 c**:

      • 将 1 个盘子从 b 移动到 a
      • 将 1 个盘子从 b 移动到 c
      • 将 1 个盘子从 a 移动到 c

    完善后的代码

    在示例中,递归函数调用和 move 方法的顺序都是符合汉诺塔问题的解决步骤的,因此代码没有问题。完善的代码增加了注释,并可以通过调整 numberOfDisks 的值来测试不同数量盘子的情况。

    如果你有任何进一步的问题或特定的改进要求,请告诉我!

    评论

报告相同问题?

问题事件

  • 创建了问题 7月31日

悬赏问题

  • ¥15 关于将inet引入的相关问题
  • ¥15 关于一个倒计时的操作和显示设计
  • ¥15 提问STK的问题,哪位航天领域的同学会啊
  • ¥15 苹果系统的mac m1芯片的笔记本使用ce修改器使用不了
  • ¥15 单相逆变的电压电流双闭环中进行低通滤波PID算法改进
  • ¥15 关于#java#的问题,请各位专家解答!
  • ¥15 如何卸载arcgis 10.1 data reviewer for desktop
  • ¥15 共享文件夹会话中为什么会有WORKGROUP
  • ¥15 关于#python#的问题:使用ATL02数据解算光子脚点的坐标(操作系统-windows)
  • ¥115 关于#python#的问题:未加密前两个软件都可以打开,加密后只有A软件可打开,B软件可以打开但读取不了数据