@@ -127,8 +127,63 @@ def print_num_recursive_revserve(n):
127
127
不幸的是 python 默认不支持尾递归优化(见延伸阅读),不过一般尾递归我们可以用一个迭代来优化它。
128
128
129
129
130
- # 著名的汉诺塔问题
130
+ # 汉诺塔问题
131
131
132
+ 有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
133
+ 但是有两个条件:
134
+
135
+ - 每次只能移动一个圆盘;
136
+ - 大盘不能叠在小盘上面。
137
+
138
+ > 最早发明这个问题的人是法国数学家爱德华·卢卡斯。
139
+ > 传说越南河内某间寺院有三根银棒,上串64个金盘。寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子;预言说当这些盘子移动完毕,世界就会灭亡。
140
+ > 这个传说叫做梵天寺之塔问题(Tower of Brahma puzzle)。但不知道是卢卡斯自创的这个传说,还是他受他人启发。
141
+
142
+
143
+
144
+ ![ 五个盘子的汉诺塔问题] ( ./hanoi_tower.png )
145
+
146
+ 理解这个问题需要我们一些思维上的转换,因为我们正常的思维可能都是从上边最小的盘子开始移动,但是这里我们从移动最底下的盘子开始思考。
147
+ 假设我们已经知道了如何移动上边的四个盘子到 B(pole2),现在把最大的盘子从 A -> C 就很简单了。当把最大的盘子移动到
148
+ C 之后,只需要把 B 上的 4 个盘子从 B -> C 就行。(这里的 pole1, 2, 3 分别就是 A, B, C 杆)
149
+
150
+ ![ ] ( ./hanoi_four_disks.png )
151
+
152
+ 问题是仍要想办法如何移动上边的 4 个盘子,我们可以同样的方式来移动上边的 4 个盘子,这就是一种递归的解法。
153
+ 给定 n 个盘子和三个杆分别是 源杆(Source), 目标杆(Destination),和中介杆(Intermediate),我们可以定义如下递归操作:
154
+
155
+ - 把上边的 n-1 个盘子从 S 移动到 I,借助 D 杆
156
+ - 把最底下的盘子从 S 移动到 D
157
+ - 把 n-1 个盘子从 I 移动到 D,借助 S
158
+
159
+ 我们把它转换成代码:
160
+
161
+ ``` py
162
+ def hanoi_move (n , source , dest , intermediate ):
163
+ if n >= 1 : # 递归出口,只剩一个盘子
164
+ hanoi_move(n- 1 , source, intermediate, dest)
165
+ print (" Move %s -> %s " % (source, dest))
166
+ hanoi_move(n- 1 , intermediate, dest, source)
167
+ hanoi_move(3 , ' A' , ' C' , ' B' )
168
+
169
+ # 输出,建议你手动模拟下。三个盘子 A(Source), B(intermediate), C(Destination)
170
+ """
171
+ Move A -> C
172
+ Move A -> B
173
+ Move C -> B
174
+ Move A -> C
175
+ Move B -> A
176
+ Move B -> C
177
+ Move A -> C
178
+ """
179
+ ```
180
+
181
+ <center >
182
+ ![ 三个盘子的汉诺塔解法] ( ./hanoi.gif )
183
+ </center >
184
+
185
+ 是不是很神奇,但是老实说这个过程仅凭大脑空想是比较难以想象出来的。人的大脑『栈』深度很有限,因为你甚至都没法同时记住超过 8 个以上的
186
+ 无意义数字,所以用大脑模拟不如用纸笔来模拟下。(不排除有些聪明的同学能迅速在脑瓜里完成这个过程)
132
187
133
188
# 延伸阅读
134
189
递归是个非常重要的概念,我们后边的数据结构和算法中还会多次碰到它,我建议你多阅读一些资料加深理解:
@@ -137,6 +192,7 @@ def print_num_recursive_revserve(n):
137
192
- 《Data Structures and Algorithms in Python》 第 10 章 Recursion
138
193
- [ 《Python开启尾递归优化!》] ( https://segmentfault.com/a/1190000007641519 )
139
194
- [ 尾调用优化] ( http://www.ruanyifeng.com/blog/2015/04/tail-call.html )
195
+ - [ 汉诺塔] ( https://zh.wikipedia.org/wiki/%E6%B1%89%E8%AF%BA%E5%A1%94 )
140
196
141
197
# 思考题
142
198
- 你能举出其他一些使用到递归的例子吗?
0 commit comments