汉诺塔问题(C语言)

本文详细介绍了汉诺塔问题的背景、规则及解决方案,通过递归算法展示了如何用C语言实现汉诺塔的移动过程。并提供了一个简单的C语言代码示例,演示了将n个盘子从A柱移动到C柱的过程,同时给出了如何统计移动步骤的思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、汉诺塔是什么

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


二、注意事项

  1. 初始条件: A 柱上有 64 个盘子, 盘子大小不等, 小盘在上,大盘在下。
  2. 完成目标:将 A 柱上的盘子最终全部移动到 C 柱。
  3. 限制条件:每次只允许移动 1 个盘子, 并始终保持小盘在上,大盘在下。

三、初步分析

为了方便理解, 讨论以下情形:

  1. disk = 1 时,
    (1)将 A 柱上的圆盘移动到C柱上即可,可标记为 A -->C

  2. disk = 2 时,
    2.1 将 A 柱上的1个盘子移动到 B 柱,可标记为 A --> B

    2.2 将 A 柱上的最后一个圆盘,从 A 柱移动到 C 柱,可标记为 A–> C

    2.3 将 B 柱上的圆盘,从 B 柱移动到 C 柱,可标记为 B–>C

  3. disk = 3 时,

    3.1 将 A 柱的 2 个盘子借助 C 柱通过一些变换可移动到 B 柱,可标记为 A --> B

    3.2 将 A 柱剩余的最后 1 个盘子,从 A 柱移动到 C 柱,可标记为 A–> C

    3.3 将 B 柱上 2个圆盘,通过一些变换借助 A 柱,可从 B 柱移动到 C 柱,可标记为 B–>C

以此类推,若有 n 个盘子,可先将除最后一个盘子以外的其他 n - 1 个盘子从 A 柱通过借助 C 柱达到全部放在 B 柱的目的,然后将第 n 个盘子(即最大的盘子)从 A 柱放在 C 柱,再将 B 柱上剩余的 n - 1 个盘子从 B 柱 通过借助 A 柱,最终达到放在 C 柱的目的

提示:1.由于当 A 柱只有一个盘子时,可直接放在 C 柱,因此可作为递归程序的出口

hanoi(int num , a, b, c)

num:盘子的数量

a,b,c可理解为从a经由b到达c


代码实现

#include <stdio.h>

/*
 * 汉诺塔问题
 */

void move(char a, char c) {
    printf("%c -> %c\n", a, c);
}

void hanoi(int num, char a, char b, char c) {
    // 递归出口就是当只有一个人盘子的时候,直接移动即可
    if (num == 1) {
        move(a, c);
    } else {
        //若有 num 个盘子,只需要将 num - 1 个盘子从 A 柱通过 C 柱放在 B 柱
        hanoi(num - 1, a, c, b);
        //然后将第 num 个盘子(即最大的盘子)从 A 柱放在 C 柱即可
        move(a, c);
        // 将 num - 1 个盘子从 B 柱 通过 A 柱放在 C柱即可
        hanoi(num - 1, b, a, c);
    }

}

int main() {
    int num;
    // A, B, C 代表三个柱子
    char a = 'A';
    char b = 'B';
    char c = 'C';
    printf("please input the number of diskes: ");
    // num 表示输入盘子的数量
    scanf("%d", &num);
    hanoi(num, a, b, c);
    return 0;
}

如果想要统计具体步骤的次数,设置一个变量,每次移动加1即可

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值