算法-图解汉诺塔原理-python3实现-可输出圆盘编号

本文详细介绍了汉诺塔问题,并使用Python3进行实现。通过递归方法,将问题分解为移动n-1个圆盘至辅助柱、移动最大圆盘至目标柱、再移动n-1个圆盘至目标柱的三个步骤。同时,提供了自定义输出圆盘编号的功能,以满足不同需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0.摘要

本文使用python3实现汉诺塔问题。 

 

1.问题阐述与分析

有三个柱子A,B,C,每个柱子上都可以放置圆盘。最初,所有圆盘都在A柱子上,需要把所有圆盘都移动到C柱子上。

要求:

1.每次只移动一个圆盘

2.只能移动柱子最上面的圆盘

3.保证每根柱子上,上面的圆盘一定比下面的圆盘小

 

经过分析,我们发现,这样的问题可以分解为下面三个子步骤

step1:如果想把A柱子上的圆盘都移动到C柱子上,那么必须先想办法把A柱子上n-1个圆盘移动到B柱子上。

不难看出,“把A柱子上圆盘移动到B柱子上”和“把A柱子上的圆盘都移动到C柱子上”,这是同一类问题。区别只不过圆盘数量变为了n-1,source是A柱子,target是B柱子。

step2:这时候可以把最大的圆盘移动到C柱子上。并且由于这个圆盘是最大的,所以其他任意圆盘都可以放在C柱子上。这时候的C柱子,和空柱子具有相同的作用。

step3:这时候,我们发现,问题转换成了如何把B柱子上n-1个圆盘移动到C柱子上?

不难看出,“把B柱子上圆盘移动到C柱子上”和“把A柱子上的圆盘都移动到C柱子上”,又是同一类问题。区别只不过圆盘数量变为了n-1,source是B柱子,target是C柱子。

 

2.代码实现

通过上面的分析,我们发现:

当需要移动的圆盘数量n=1时,直接移动圆盘即可;

当需要移动的圆盘数量n>1时,这个问题都可以转化成n-1个圆盘的问题。

#coding=utf-8
def hanoi(n,a,b,c):
    if n == 1:
        print(a , ' --> ',c)
    else:
        hanoi(n-1,a,c,b)
        hanoi(1,a,b,c)
        hanoi(n-1,b,a,c)

if __name__ == '__main__':
    hanoi(3,'A','B','C')

 

3.自定义输出方式

有些问题中,我们除了输出圆盘移动路径之外,还需要输出其他的信息,比如每次移动的是哪个圆盘。

在这里,本文给出一个示例,输出圆盘编号,仅供参考:

#coding=utf-8
import numpy as np

def print_message(a,c):
    if not a :
        print('Something wrong in data!')
        return -1
    disk = a['disks'].pop()
    c['disks'].append(disk)
    print(disk,end='#')
    print(a['name'], ' --> ', c['name'])
    return 0

def hanoi(n,a,b,c):
    if n == 1:
        print_message(a,c)
    else:
        hanoi(n-1,a,c,b)
        hanoi(1,a,b,c)
        hanoi(n-1,b,a,c)

if __name__ == '__main__':
    disks_num = 3
    disks = np.arange(disks_num,0,-1).tolist()
    A = {'name':'A','disks':disks}
    B = {'name':'B','disks':[]}
    C = {'name':'C','disks':[]}
    # print(A,B,C)
    hanoi(disks_num,A,B,C)

这里通过字典的方式,存储了每个柱子的名称和堆放的圆盘信息。

与第2节的程序相比,将输出函数单写,具体功能可根据需要定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值