采用递归算法求解汉诺塔问题

本文详细介绍了汉诺塔问题的起源、数学抽象、算法分析及其实现。通过递归算法,解析了移动圆盘的步骤和次数,展示了如何将n个盘子从一根柱子移动到另一根柱子的全过程。

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

一.起源:

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

二.抽象为数学问题:

如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数。

解:

(1)n = 1时

    第1次  1号盘  A---->C       sum = 1 次

  (2)  n = 2时

   第1次  1号盘  A---->B

   第2次  2号盘  A---->C

   第3次  1号盘  B---->C        sum = 3 次

(3)n = 3时

   第1次  1号盘  A---->C

 第2次  2号盘  A---->B

    第3次  1号盘  C---->B

    第4次  3号盘  A---->C

    第5次  1号盘  B---->A

 第6次  2号盘  B---->C

    第7次  1号盘  A---->C        sum = 7 次

发现规律:1个圆盘的次数 2的1次方减1

        2个圆盘的次数 2的2次方减1

                  3个圆盘的次数 2的3次方减1

                   。  。   。    。   。 

                   n个圆盘的次数 2的n次方减1

 故:移动次数为:2^n - 1

三.算法分析(递归算法):

在利用计算机求汉诺塔问题时,必不可少的一步是对整个实现求解进行算法分析。到目前为止,求解汉诺塔问题最简单的算法通过递归来求,至于什么是递归,递归实现的机制是什么,简单点就是自己是一个方法或者是函数,但是在自己这个函数里有调用自己这个函数的语句,而这个调用怎么才能调用结束呢?,这里还必须有一个结束点,或者具体的说是在调用到某一次后函数能返回一个确定的值,接着倒数第二个就能返回一个确定的值,一直到第一次调用的这个函数能返回一个确定的值。

实现这个算法简单分为三个步骤:

  (1)把n-1个盘子由A 移到 B

  (2)把第n个盘子由 A移到 C

  (3)把n-1个盘子由B 移到 C

不难发现,移到的步数必定为奇数步:

       (1)中间的一步是把最大的一个盘子由A移到C上去

       (2)中间一步之上可以看成把A上n-1个盘子通过借助辅助塔(C塔)移到了B上

       (3)中间一步之下可以看成把B上n-1个盘子通过借助辅助塔(A塔)移到了C上

四.算法实现

/**
*    实验题目:
*        采用递归算法求解汉诺塔问题
*    实验目的:
*        领会基本递归算法设计
*    实验内容:
*        采用递归方法求解汉诺塔问题,输出3个盘片的移动过程
*/

#include <stdio.h>

/*--------------------递归算法----------------------*/
/**
*   汉诺塔递归算法
*   @param a: 起始柱子
*   @param b: 辅助柱子
*   @param c: 目标柱子
*/
static void hanoi(int n, char a, char b, char c)
{
    if(n == 1)
        printf("\t将第%d个盘片从%c移动到%c\n", n, a, c);
    else
    {
        // 把A上n-1个盘子通过借助辅助塔(C塔)移到了B上
        hanoi(n - 1, a, c, b);
        printf("\t将第%d个盘片从%c移动到%c\n", n, a, c);
        // 把B上n-1个盘子通过借助辅助塔(A塔)移到了C上
        hanoi(n - 1, b, a, c);
    }
}

int main(int argc, char *argv[])
{
    int n = 3;

    printf("递归算法: %d个盘片移动过程:\n", n);
    hanoi(n, 'A', 'B', 'C');

    return 0;
}
测试结果:

递归算法: 3个盘片移动过程:
        将第1个盘片从A移动到C
        将第2个盘片从A移动到B
        将第1个盘片从C移动到B
        将第3个盘片从A移动到C
        将第1个盘片从B移动到A
        将第2个盘片从B移动到C
        将第1个盘片从A移动到C

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值