用栈来求解汉诺塔问题(python)

# 用栈来求解汉诺塔问题


# 方法一:递归的方法
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))

 

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值