汉诺塔的 Go 语言实现
汉诺塔,数据结构和算法里老生常谈的东西了,可惜我至今没有彻底透彻的搞清楚它的递归细节。现在利用学习 Go 语言的机会,再重新理清一下它的实现和递归的本质。
先上代码:
1 | package main |
我现在理解的递归的本质就是用把 n 级的问题用 n-1 级定义出来,找出所谓的递归结构,进而找出递推公式。对于汉诺塔问题,就是要抽象出以下4个变量:n, x, y, z。n 代表问题规模,即 n 层盘子,x, y, z 分别表示源柱,目标柱和过渡柱。函数内部就是聚焦于这4个变量的操作:
- 把 n-1 个盘子从源柱经过目标柱的过渡,挪到过渡柱(从而使源柱上只有第 n 个盘子)
- 把第 n 个盘子从源柱上挪到目标柱上(程序输出这个单步的操作)
- 把过渡柱上的 n-1 个盘子经过源柱挪到目标柱上
这样通过递归,n 的规模不断减小,直到 n == 0,同类问题的最小规模情况,对于这个最小规模情况,我们知道确切的答案,就是不做任何操作(直接 return),进而触发了递归的反向求值连锁反应。所以,递归其实就是这样一个过程:
- 第 n 层答案 = 第 n-1 层答案 + 固定已知计算
- 第 n-1 层答案 = 第 n-2 层答案 + 固定已知计算
- ……
- 第 0或1 层答案 = 一个确定已知答案
前面每层的答案都等待着下一层的答案再加上一个已知计算,一直到第1层或者第0层有一个已知答案,进而第2层因为第1层有了答案而有了答案,第3层因为第2层有了答案而有了答案……一直到第 n 层因为第 n-1 层有了答案而有了答案,于是整个问题有了解。