You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.8 KiB
69 lines
1.8 KiB
package cap3
|
|
|
|
import "lavos/common"
|
|
|
|
// Ex5 例题5 汉诺塔问题,输出移动的步骤,可指定算法类型,每做出一步移动操作都将会调用callback
|
|
func Ex5(beadNum int, algoType AlgoType, callback func(from string, to string)) {
|
|
switch algoType {
|
|
case AlgoTypeRecursion:
|
|
Ex5Recursive(beadNum, "A", "B", "C", callback)
|
|
default:
|
|
Ex5NonRecursive(beadNum, "A", "B", "C", callback)
|
|
}
|
|
}
|
|
|
|
func Ex5Recursive(beadNum int, a, b, c string, callback func(from string, to string)) {
|
|
if beadNum == 1 {
|
|
// 如果只有一颗珠子,直接从 A 移动到 C,结束
|
|
callback(a, c)
|
|
} else {
|
|
// 第二步:将所有在 N 之上的珠子(即 N-1 颗珠子)从 A 移动到 B。此时 C 是中转站
|
|
Ex5Recursive(beadNum-1, a, c, b, callback)
|
|
|
|
// 第二步:将 A 的珠子移动到 C
|
|
callback(a, c)
|
|
|
|
// 第三步:将剩余的 N-1 颗珠子从 B 移动到 C。此时 A 是中转站
|
|
Ex5Recursive(beadNum-1, b, a, c, callback)
|
|
}
|
|
}
|
|
|
|
type _step struct {
|
|
n int
|
|
from, transit, to string
|
|
}
|
|
|
|
func Ex5NonRecursive(beadNum int, a, b, c string, callback func(from string, to string)) {
|
|
stack := common.NewStack[_step](beadNum * 5)
|
|
// 最终状态:a->c,b作为中转
|
|
stack.Push(&_step{
|
|
n: beadNum,
|
|
from: a, transit: b, to: c,
|
|
})
|
|
for !stack.Empty() {
|
|
status := stack.Pop()
|
|
if status.n == 1 {
|
|
callback(status.from, status.to)
|
|
} else {
|
|
// 把子问题的三个基本步骤压入栈
|
|
stack.Push(&_step{
|
|
n: status.n - 1,
|
|
from: status.transit,
|
|
transit: status.from,
|
|
to: status.to,
|
|
})
|
|
stack.Push(&_step{
|
|
n: 1,
|
|
from: status.from,
|
|
transit: status.transit,
|
|
to: status.to,
|
|
})
|
|
stack.Push(&_step{
|
|
n: status.n - 1,
|
|
from: status.from,
|
|
transit: status.to,
|
|
to: status.transit,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|