汉诺塔游戏规则:游戏里有三根金刚石柱子,在A柱子上从下往上安从大到小顺序摞着64片黄金圆盘。玩家需要做的是把圆盘从下面开始按大小顺序重新摆放在C柱子上,利用B柱子作为过渡。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
游戏理解起来很简单,我们小时候应该都玩过,那么怎么用程序来模拟这一过程呢?在这里,我们可以用递归思想,问题将很容易得到解决。那么什么是递归思想,递归又应该如何使用呢?下面我将参照嵩天老师的递归函数课程来做一次粗略的介绍与总结。
一、什么是递归?
递归就是在函数内部调用自身。
二、递归的基本条件
1.函数+分支结构
举例:
def func(n):
if:
xxx
else:
xxx
2.递归基例
一个或多个不需要再次递归的基例
3.递归链条
计算过程中,存在的紧密相连,密不可分的关系
打个比方:我喜欢班上的一个叫金大蕾的女生,但是我坐在最后一排而她在第一排,那么我该怎么向她表达我的倾慕之心呢?于是我灵机一动,写了个小纸条让坐在倒是第二排的同学帮忙向前传,他让倒数第三排的人再往前传,就这样一直传到了第一排大蕾的手上。然后她也回了个小纸条,通过一个个同学的帮忙终于反馈给我了。这里,我们每一排同学之间构成了一个递归链条,运用这个链条把每一排联系起来,中间他们怎么传的我不关心,我只关心我跟前面一个同学是否传达正确。假使我跟他同桌,就不存在所谓的链条关系,我们一句对话即可达成目的,这就是递归基例。
那么针对这个汉诺塔问题,假使它只有一个圆盘,我们只需要把他从A拿到C即可完成,中间甚至都可以不借助B柱子。这就是一个基例。
然后针对N个圆盘,我们可以把上面N-1个圆盘先拿到B柱子上去,再把第N个圆盘拿到C柱子,最后再把N-1个圆盘拿到C上。即可完成一次汉诺塔游戏全过程,代码如下:
# -*- coding: utf-8 -*-
count = 0
def hanoi(n,src,dst,mid):
"""汉诺塔函数,将n个圆盘从源柱子通过中间柱子最后都搬去目的柱子"""
global count
if n == 1:
print("{}:{}->{}".format(n,src,dst)) #将1个圆盘从源柱子拿到目的柱子去
count += 1 #完成一次搬运,计数+1
else:
hanoi(n-1,src,mid,dst) #将n-1个柱子从源柱子通过目的柱子的过渡,全部搬到中间柱子
print("{}:{}->{}".format(n,src,dst)) #打印将第n个圆盘从源柱子拿到目的柱子
count += 1
hanoi(n-1,mid,dst,src) #最后将n-1个柱子从源柱子通过中间柱子的过渡,全部搬到目的柱子
hanoi(5,"A","B","C")
print(count)
最后附上嵩天老师的课程视频:汉诺塔游戏之递归函数的应用