关于汉诺塔问题(n,A,B,C)的一些理解

关于汉诺塔问题(n,A,B,C)的一些理解

对于汉诺塔问题(n,A,B,C)网上给出的很多解答都没有较为详细的解释,只有大致的几处注释,对于代码中的x,y,z的变换问题也没有解释为什么。抽象的分析思路固然是递归的特点,但是对于这个问题里递归如何工作以及x,y,z的变化如何实现对于初次接触递归和汉诺塔问题的人来说十分重要。
本次仅讨论3根柱子的汉诺塔问题。
代码如下:

#include<stdio.h>
void h(int n,char x,char y,char z)
{
    if(n==1)
        printf("%d:%c-->%c\n",n,x,z);
    else
    {
        h(n-1,x,z,y);
        printf("%d:%c-->%c\n",n,x,z);
        h(n-1,y,x,z);
    }
}
int main()
{
    h(n,'A','B','C');
    return 0;
}

问题解释:
有三根柱子A,B,C依次,A上面有n个盘,要挪到C上面去, h(n,‘A’,‘B’,‘C’)函数整体是说将n个盘借助B挪到C上面去,调用第一次函数运行 h(n-1,x,z,y)一步,是说要将第n个盘挪到C必须要将上面的n-1个盘子挪到B,继续调用 运行h(n-2,x,z,y)一步,要将第n-1个盘挪到B必须要将上面的n-2个盘挪到C(要注意到在不断的给形参传输数据的时候x,y,z所代表的值在不断变化),如此往复,最后得要将第二盘移到B/C中的某根柱子上需要将第一个盘挪到C/B柱子上,挪动之后,结果是第n个盘被移动到了B或者C中的某一根柱子上,而未曾参与y,z柱子转换的x上没有盘子,另一根柱子上有n-1个盘,程序运行printf(“%d:%c–>%c\n”,n,x,z)一步(此时值为n,表示本步移动的是第n个盘),得到的与开始的情况相似。
我们可以不看最大的盘子,问题就类似于开始盘子数为n-1的情况,整体的目的是借助x这个空柱子将n-1个盘子挪到放有最大盘子的柱子上,h(n-1,y,x,z)这一步的目的是将这个有n-1个盘子的柱子上的第n-1个盘子借助x这个空柱子挪到放有最大盘子的柱子上,此时又进入递归,理解同有n个盘子时的情况。
我们每运行完一次else{}中的三步(中间有很多次递归),所属情况下最大的盘子就被移动到被期待到达的位置,而每一次这三大部分运行完毕都会进行一次,x,y,z对应A,B,C值的变换,我们只需要考虑移动第n个盘(即最初始情况)即可得到变换关系:第一次x,y,z对应A,B,C,挪完最大盘后,x空,y有n-1个盘,z有一个最大盘(挪完可以不考虑),目的是将y上的最大盘借助x挪到z上,于是调用函数为h(n-1,y,x,z),这就解释了x,y,z的数值变换方式是什么。
以上是我对汉诺塔问题(n,A,B,C)的一些理解,有误之处请批评指正。

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/yuxin199/article/details/84343640
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞