汉诺塔问题的分析及代码


2019-10-16做些补充:

其实很简单,有n个盘子,3个柱子,无非就是把n-1个盘子先借助目标柱放到temp柱上,把n从起始柱,挪到目标柱,最后再把n-1个盘子从temp柱,借助起始柱,挪到目标柱上。

汉诺塔问题的分析及代码_第1张图片

汉诺塔问题的分析及代码_第2张图片


以下为原答案:


汉诺塔是一个很有名的益智游戏也是个常见的递归算法的例子。

(说明:下面所述均为参考鱼C工作室的小甲鱼数据结构与算法的课程之后自己所写)

问题描述:

如图有三个盘子针,分别为X、Y、Z。

我们要做的事是:将64个盘子从X针移到Z针。(盘子们肯定是在三个针上来回移动从而达到目的)

要求:每次只能移动一个盘子;

           小的盘子必须放在比它大的盘子之上。

汉诺塔问题的分析及代码_第3张图片


 

抽象一下整体的思路(分为三步):

步骤一:把63个较小的盘子从X针挪到Y针(挪动期间保证小盘在上大盘在下);

步骤二:把第64个也就是最大的盘子挪到Z针;

步骤三:把Y针上的63个盘子挪到Z针上。


但是上述的步骤一和步骤三好实现吗?

比如步骤一     --------   把63个较小的盘子从X针挪到Y针(挪动期间保证小盘在上大盘在下)

我们能直接将63个盘子从X挪到Y吗?显然不能。

这个挪动过程我们还需要借助Z针。

所以可以再整理一下我们遇到的问题:

问题一:将X针上的63个盘子借助Z针挪到Y针上;

问题二:将Y针上的63个盘子借助X针挪到Z针上。


具体来看问题一(将X针上的63个盘子借助Z针挪到Y针上)。

源:X针    中介:Z针    目的:Y针

问题一的解决步骤:

      步骤一:先将62个盘子从X针挪到Z针;

      步骤二:再将第63个大盘子直接挪到目的针Y针上;

      步骤三:最后将挪到中介针Z针上的62个较小的盘子挪到目的针Y针上。


再来看问题二(将Y针上的63个盘子借助X针挪到Z针上)

源:Y针   中介针:X针     目的针:Z针

问题二的解决步骤:

      步骤一:先将62个盘子从Y针挪到中介针X针;

      步骤二:再将第63个大盘子直接挪到目的针Z针上;

      步骤三:最后将挪到中介针X针上的62个较小的盘子挪到目的针Z针上。


我们可以发现:这些问题一和问题二的解决方法是有共同点的。

问题一可以往下一步一步地递归,直到盘子数为1的时候,从源针直接挪到目的针上。

问题二同样可以一步步往下递归,直到盘子数为1的时候,从源针直接挪到目的针上。

至此,我们就看到了递归的样子。


理清思路之后,我们尝试写一下代码。

C语言版:

#include

void doTowers(int n,char X,char Y,char Z){
    if(n == 1)
        printf("Dish 1 from %c to %c \n",X,Z);
    else{
        doTowers(n-1,X,Z,Y);   //先将n-1个盘子借助Z从X挪到Y,为了方便将最下面的盘子直接挪到目的针
        printf("Dish %d from %c to %c \n",n,X,Z);   //把最下面的盘子直接从源挪到目的
        doTowers(n-1,Y,X,Z);  //把移到Y针上的n-1个盘子再挪到最终目的针Z上
    }
}
int main(){
    int n;
    printf("Enter the count of dishes: \n");
    scanf("%d",&n);
    printf("The answer is :\n");
    doTowers(n,'X','Y','Z');         //参数分别为:盘子数、源、中介、目标
}

运行结果:

汉诺塔问题的分析及代码_第4张图片


Java版:

class towersApp{
    public static void main(String[] args){
        doTowers(3,'X','Y','Z');
    }
    
    public static void doTowers(int n,char X,char Y,char Z){
        if(n == 1){
            System.out.println("Dish 1 from "+X+" to "+Z);
        }else{
            doTowers(n-1,X,Z,Y);
            System.out.println("Dish "+ n + " from "+X+" to "+Z);
            doTowers(n-1,Y,X,Z);
        }
    }
}

运行结果:

汉诺塔问题的分析及代码_第5张图片

 

到这里我们的汉诺塔问题就结束啦!

期待下一个递归问题(头有点秃)

你可能感兴趣的:(数据结构与算法)