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!
接下来进入分治的思想。汉诺塔问题可以分为三步:
- 将A上n-1个圆盘移动到B。(临界状态1)
- 将A剩下最大的圆盘移动到C。(一步)
- 再将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指图中的柱子)。
我不知道有没有人有过这个疑惑,就是为什么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的情况。
因为当
n
=
3
n=3
n=3时,就是要把上面的
n
=
3
−
1
=
2
n=3-1=2
n=3−1=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的情况。
为什么不能放到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(n−1)+1。
综上所述,我用了几个关键的状态来表示递归的过程,即从图1到图2再到图3。而实际上,我们自己用手推导或者摆放的最小开销过程是从图3到图2最后到图1。此外,我在另一篇博文对n=4的情况进行了图解,可以帮助你加深理解。
希望对你的理解有所帮助,觉得不错不妨点个赞支持一下博主。