# 用栈来求解汉诺塔问题
# 方法一:递归的方法
def hanoiProblem(num:int, left:str, mid:str, right:str)->int:
if num < 1:
return 0
return process(num, left, mid, right, left, right)
def process(num:int, left:str, mid:str, right:str, from_:str, to:str)->int:
if num == 1:
if from_ == mid or to == mid:
print("Move 1 from " + from_ + " to " + to)
return 1
else:
print("Move 1 from " + from_ + " to " + mid)
print("Move 1 from " + mid + " to " + to)
return 2
if from_ == mid or to == mid:
another = right if from_==left or to==left else left
part1 = process(num-1, left, mid, right, from_, another)
part2 = 1
print("Move " + str(num) + " from " + from_ + " to " + to)
part3 = process(num-1, left ,mid, right, another, to)
return part1 + part2 + part3
else:
part1 = process(num-1, left, mid, right, from_ , to)
part2 = 1
print("Move " + str(num) + " from " + from_ + " to " + mid)
part3 = process(num-1, left ,mid, right, to, from_)
part4 = 1
print("Move " + str(num) + " from " + mid + " to " + to)
part5 = process(num-1 , left, mid, right, from_, to)
return part1 + part2 + part3 + part4 + part5
# 方法二:非递归的方法————用栈来模拟整个过程
from enum import Enum, unique # 枚举类
@unique
class Action(Enum):
No = 'No'
LToM = 'LToM'
MToL = 'MToL'
MToR = 'MToR'
RToM = 'RToM'
def hanoiProblem2(num:int, left:str, mid:str, right:str)->int:
# 栈用列表代替,加入int32最大整数,是为了最后遍历四个操作不会报错
lS = [2**31-1] # 左
mS = [2**31-1] # 中
rS = [2**31-1] # 右
lS += [i for i in range(num, 0, -1)] # 初始化
record = [Action.No]
step = 0
while len(rS) != num + 1:
step += fStackTotStack(record, Action.MToL, Action.LToM, lS, mS, left, mid)
step += fStackTotStack(record, Action.LToM, Action.MToL, mS, lS, mid, left)
step += fStackTotStack(record, Action.RToM, Action.MToR, mS, rS, mid, right)
step += fStackTotStack(record, Action.MToR, Action.RToM, rS, mS, right, mid)
return step
def fStackTotStack(record:list, preNoAct:Action, nowAct:Action,
fStack:list, tStack:list, from_:str, to:str)->int:
if record[0] != preNoAct and fStack[-1] < tStack[-1]:
tStack.append(fStack.pop())
print("Move " + str(tStack[-1]) + " from " + from_ + " to " + to)
record[0] = nowAct
return 1
return 0
if __name__ == "__main__":
# 方法一
res = hanoiProblem(3, 'left', 'mid', 'right')
print("总共移动{}次".format(res))
# 方法二
res = hanoiProblem2(3, 'left', 'mid', 'right')
print("总共移动{}次".format(res))