我对汉诺塔问题的理解

1、代码的实现

  这一段代码非常简单,网上一大堆。但真正理解起来,却没这么简单。所以接下来我想以我的方式,解释一下分治的过程。

2、问题重述

  假设现在一共有 n n n个圆盘在圆柱 A A A上,假设现在 n = 4 n=4 n=4。我们的目标是,通过最少的移动次数,将从大到小堆叠起来的圆盘,移动到圆柱 C C C。值得注意的是,移动的规则是:大的圆盘不能放到小的圆盘上,而且一次只能移动一个圆盘。
  定义函数 F u n c ( n , a , b , c ) Func(n,a,b,c) Func(n,a,b,c),可以理解为递归中当前栈的状态,表示圆柱a上一共有n个圆盘,要借助b(但不是只将b作为辅助柱,a、c都会在移动的过程中起到辅助的作用),将 n n n个圆盘移动到c。注意: a , b , c a,b,c a,b,c代表圆柱 A , B , C A,B,C A,B,C的具体值。注意,在递归的参数传递过程中,A不一定是a!
  接下来进入分治的思想。汉诺塔问题可以分为三步:

  1. 将A上n-1个圆盘移动到B。(临界状态1)
  2. 将A剩下最大的圆盘移动到C。(一步)
  3. 再将B上n-1个圆盘移动到C。(临界状态2

  这个步骤一定是最小的开销。如果你认同这个结论,那么我们接着走。当 n = 4 n=4 n=4的时候,主函数为 F u n c ( n : 4 , A : a , B : b , C : c ) Func(n:4,A:a,B:b,C:c) Func(n:4,A:a,B:b,C:c),在这个函数中我们将开启分治思想+递归逻辑解决问题的旅程。

3、我的理解

   F u n c ( n : 4 , A : a , B : b , C : c ) Func(n:4,A:a,B:b,C:c) Func(n:4,A:a,B:b,C:c)临界状态1即Func(n:3,A:a,B:c,C:b) 如下图1所示。其中,n代表从小到大选择A上的n个圆盘,但不一定就是a。这意味着对当前A上的4个圆盘来说(初始状态),一定存在将3个圆盘从A移动到B的情况(这里的A,B指图中的柱子)。
1
  我不知道有没有人有过这个疑惑,就是为什么C和B要在递归中反复交替?如何确定n=1的时候放在B还是放在C?其实就是反复地按照该汉诺塔问题的三个步骤,将大问题化为三个小问题,反复交替。我们接下来看:
   F u n c ( n : 3 , A : a , B : c , C : b ) Func(n:3,A:a,B:c,C:b) Func(n:3,A:a,B:c,C:b)临界状态1即Func(n:2,A:a,B:b,C:c) 如下图2所示。这意味着在图1在B上的3个圆盘之前,一定存在将2个圆盘从A移动到C的情况。
2
  因为当 n = 3 n=3 n=3时,就是要把上面的 n = 3 − 1 = 2 n=3-1=2 n=31=2的圆盘放到B或者C。但是如果放到B的话,那A中最顶上的圆盘只能放到C了,显然不能符合最小的开销达到 F u n c ( n : 4 , a : A , b : B , c : C ) Func(n:4,a:A,b:B,c:C) Func(n:4,a:A,b:B,c:C)的临界状态1。
   F u n c ( n : 2 , A : a , B : b , C : c ) Func(n:2,A:a,B:b,C:c) Func(n:2,A:a,B:b,C:c)临界状态1即Func(n:1,A:a,B:c,C:b) 如下图3所示。这意味着.图2在移动到C上的2个圆盘之前,一定存在将1个圆盘从A移动到B的情况。
3
  为什么不能放到C呢,因为从图3到图2,最快的开销肯定是将最小的圆盘放到B而不是放到C。这是显而易见的。
   F u n c ( n : 2 , A : a , B : c , C : b ) Func(n:2,A:a,B:c,C:b) Func(n:2,A:a,B:c,C:b)进入 F u n c ( n : 1 , A : a , B : c , C : b ) Func(n:1,A:a,B:c,C:b) Func(n:1,A:a,B:c,C:b)的栈后会抵达递归的终止条件,而 F u n c ( n : 1 , A : a , B : c , C : b ) Func(n:1,A:a,B:c,C:b) Func(n:1,A:a,B:c,C:b)的意思就是将第一个且最小的圆盘从A移动到B。不知道看到这里,你的理解是否加深了。
  同理,临界状态2也能这样推理,且与临界状态1的总开销一样。即, T ( n ) = 2 × T ( n − 1 ) + 1 T(n)=2 \times T(n-1)+1 T(n)=2×T(n1)+1
  综上所述,我用了几个关键的状态来表示递归的过程,即从图1到图2再到图3。而实际上,我们自己用手推导或者摆放的最小开销过程是从图3到图2最后到图1。此外,我在另一篇博文对n=4的情况进行了图解,可以帮助你加深理解。
  希望对你的理解有所帮助,觉得不错不妨点个赞支持一下博主。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TerryBlog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值