python漢諾塔問題

2022-08-01 05:54:14 字數 3752 閱讀 3602

一、漢諾塔問題

漢諾塔(又稱河內塔)問題是源於印度乙個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片**圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動乙個圓盤

二、漢諾塔問題分析

我們可以將問題簡化描述為:n個盤子和3根柱子:a(源)、b(備用)、c(目的),盤子的大小不同且中間有一孔,可以將盤子「串」在柱子上,每個盤子只能放在比它大的盤子上面。起初,所有盤子在a柱上,問題是將盤子乙個乙個地從a柱子移動到c柱子。移動過程中,可以使用b柱,但盤子也只能放在比它大的盤子上面。因此我們得出漢諾塔問題的以下幾個限制條件:

1.在小圓盤上不能放大圓盤。

2.在三根柱子之間一回只能移動乙個圓盤。

3.只能移動在最頂端的圓盤。

首先,我們從簡單的例子開始分析,然後再總結出一般規律。

當n = 1的時候,即此時只有乙個盤子,那麼直接將其移動至c即可。移動過程就是a -> c

當n = 2的時候,這時候有兩個盤子,那麼在一開始移動的時候,我們需要借助b柱作為過渡的柱子,即將a柱最上面的那個小圓盤移至b柱,然後將a柱底下的圓盤移至c柱,最後將b柱的圓盤移至c柱即可。那麼完整移動過程就是a-> b , a -> c , b -> c

當n = 3的時候,那麼此時從上到下依次擺放著從小到大的三個圓盤,根據題目的限制條件:在小圓盤上不能放大圓盤,而且把圓盤從a柱移至c柱後,c柱圓盤的擺放情況和剛開始a柱的是一模一樣的。所以呢,我們每次移至c柱的圓盤(移至c柱後不再移到其他柱子上去),必須是從大到小的,即一開始的時候,我們應該想辦法把最大的圓盤移至c柱,然後再想辦法將第二大的圓盤移至c柱......然後重複這樣的過程,直到所有的圓盤都按照原來a柱擺放的樣子移動到了c柱。

那麼根據這樣的思路,問題就來了:

如何才能夠將最大的盤子移至c柱呢?

那麼我們從問題入手,要將最大的盤子移至c柱,那麼必然要先搬掉a柱上面的n-1個盤子,而c柱一開始的時候是作為目標柱的,所以我們可以用b柱作為"暫存"這n-1個盤子的過渡柱,當把這n-1的盤子移至b柱後,我們就可以把a柱最底下的盤子移至c柱了。

而接下來的問題是什麼呢?

我們來看看現在各個柱子上盤子的情況,a柱上無盤子,而b柱從上到下依次擺放著從小到大的n-1個盤子,c柱上擺放著最大的那個盤子。

所以接下來的問題就顯而易見了,那就是要把b柱這剩下的n-1個盤子移至c柱,而b柱作為過渡柱,那麼我們需要借助a柱,將a柱作為新的"過渡"柱,將這n-1個盤子移至c柱。

三、漢諾塔的實現

因此,源**為:

def move(n,a,b,c):

if n==1:

print(a,"->",c)

else:

move(n-1,a,c,b)

print(a,'->',c)

move(n-1,b,a,c)

n=int(input(""))

move(n,'a','b','c')

執行結果:

四、用turtle庫畫出漢諾塔搬運的過程

源**如下:

import turtle

class stack: #物件導向定義乙個類

def __init__(self):

self.items =

def isempty(self):

return len(self.items) == 0

def push(self, item):

def pop(self):

return self.items.pop()

def peek(self):

if not self.isempty():

return self.items[len(self.items) - 1]

def size(self):

return len(self.items)

def drawpole_3(): #這裡是繪製三個塔柱子

t = turtle.turtle()

t.hideturtle()

def drawpole_1(k):

t.up()

t.pensize(10)

t.speed(100)

t.goto(400*(k-1), 300)

t.down()

t.goto(400*(k-1), -100)

t.goto(400*(k-1)-20, -100)

t.goto(400*(k-1)+20, -100)

drawpole_1(0)

drawpole_1(1)

drawpole_1(2)

def creat_plates(n): #按照輸入的n來畫出盤子個數

plates=[turtle.turtle() for i in range(n)]

for i in range(n):

plates[i].up()

plates[i].hideturtle()

plates[i].shape("square")

plates[i].shapesize(1,20-i)

plates[i].goto(-400,-90+20*i)

plates[i].showturtle()

return plates

def pole_stack(): #這裡運用棧來控制一次只能搬動乙個盤子並且遞迴

poles=[stack() for i in range(3)]

return poles

def movedisk(plates,poles,fp,tp): #搬動盤子

mov=poles[fp].peek()

plates[mov].goto((fp-1)*400,300)

plates[mov].goto((tp-1)*400,300)

l=poles[tp].size()

plates[mov].goto((tp-1)*400,-90+20*l)

def movetower(plates,poles,height,frompole, topole, withpole):

if height >= 1:

movetower(plates,poles,height-1,frompole,withpole,topole)

movedisk(plates,poles,frompole,topole)

poles[topole].push(poles[frompole].pop())

movetower(plates,poles,height-1,withpole,topole,frompole)

myscreen=turtle.screen()

drawpole_3()

n=int(input("請輸入漢諾塔的層數並回車確定:\n"))

plates=creat_plates(n)

poles=pole_stack()

for i in range(n):

poles[0].push(i)

movetower(plates,poles,n,0,2,1)

myscreen.exitonclick()

執行結果如圖:

故漢諾塔的搬運過程即可以得到。

python 漢諾塔 Python漢諾塔

import turtle class stack def init self self.items def isempty self return len self.items 0 def push self,item def pop self return self.items.pop def ...

python 漢諾塔問題

最近被漢諾塔的python 遞迴給迷暈,本想搞個程式除錯,但sublimetext用的不是很熟,參考了很多大佬的博文,需要總結下以防往後忘記 關於理解 流程,其實主要關注兩點 1 形參實參注意別搞混了 2 函式呼叫後都是要返回的,從哪個入口進去執行最後執行完程式是要返回回原來的入口,再執行時要注意開...

漢諾塔問題(python)

def hanoi n,a,b,c 將n個圓盤從a經過b移到c if n 0 圓盤數大於0 hanoi n 1,a,c,b 將n 1個圓盤從a經過c移到b print format a,c 將a上最底部的圓盤移到c hanoi n 1,b,a,c 將n 1個圓盤從b經過a移到c hanoi 3,a ...