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, }) } } }