题目:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘.
一般是通过递归来解决汉诺塔问题,也可以让汉诺塔问题更加面向对象一点,将塔作为对象.
解法一
核心代码:
<pre><code>` func moveTopTo(original:Tower,destination:Tower) {
if original.disks.count == 0 {
return
}
let top:Int = original.disks.last!
original.disks.removeLast()
destination.add(n: top)
print("(original.name)塔移动到→(destination.name)")
}
func moveDisks(disks:Int,original:Tower,destination:Tower,buffer:Tower) {
if disks == 1 {
moveTopTo(original: original, destination: destination)
return
}
moveDisks(disks: disks - 1, original: original, destination: buffer, buffer: destination)
moveDisks(disks: 1, original: original, destination: destination, buffer: buffer)
moveDisks(disks: disks - 1, original: buffer, destination: destination, buffer: original)
}
func move(diskCount:Int) {
var towers:[Tower] = []
towers.append(Tower(towerName: "A"))
towers.append(Tower(towerName: "B"))
towers.append(Tower(towerName: "C"))
let tower:Tower = towers[0]
for i in (0..<diskCount).reversed() {
tower.add(n: i)
}
moveDisks(disks: diskCount, original: towers[0], destination: towers[2], buffer: towers[1])
print("FlyElephant--------------")
}`</code></pre>
解法二
核心代码:
<pre><code>` func move2(diskCount:Int) {
var towers:[Tower] = []
towers.append(Tower(towerName: "A"))
towers.append(Tower(towerName: "B"))
towers.append(Tower(towerName: "C"))
for i in (0..<diskCount).reversed() {
towers[0].add(n: i)
}
towers[0].moveDisks(n: diskCount, destination: towers[2], buffer: towers[1])
}`</code></pre>
汉诺塔对象:
<pre><code>`class Tower {
var name:String = ""
var disks:[Int] = []
init(towerName:String) {
name = towerName
}
func add(n:Int) {
if disks.count > 0 {
let top:Int = disks.last!
if n >= top {
return
}
disks.append(n)
} else {
disks.append(n)
}
}
func moveTopTo(tower:Tower) {
if disks.count == 0 {
return
}
let top:Int = disks.last!
disks.removeLast()
tower.add(n: top)
print("\(self.name)塔移动到→\(tower.name)")
}
func moveDisks(n:Int,destination:Tower,buffer:Tower) {
if n > 0 {
moveDisks(n: n - 1, destination: buffer, buffer: destination) // n-1 个盘子移动到缓冲区
moveTopTo(tower: destination)
buffer.moveDisks(n: n - 1, destination: destination, buffer: self) // n-1 个盘子从缓冲区移动到目标区域
}
}
}`</code></pre>
测试代码:
<pre><code>var hanoi:Hanoi = Hanoi() hanoi.move(diskCount: 3) hanoi.move2(diskCount: 3)
</code></pre>