1. 程式人生 > >遞迴經典案例漢諾塔 python實現

遞迴經典案例漢諾塔 python實現

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

è¿éåå¾çæè¿°

 

先上程式碼:

首先看一下只有兩個盤子的情況:

def move(n, a, b, c):    #n為盤子個數,a為起始位置,b為緩衝區,c為目標位置
    if n == 1:
        print(a +"->"+ c)
    else:
        move(n-1, a, c, b)  #首先需要把 (N-1) 個圓盤移動到 b
        move(1, a, b, c)    #將a的最後一個圓盤移動到c
        move(n-1, b, a, c)  #再將b的(N-1)個圓盤移動到c


move(2, "a", "b", "c")
a->b
a->c
b->c

解讀程式碼:

move(2, a, b, c)
->n=2
  move(1, a, c, b) 
  ->n=1             a -> b
  move(1, a, b, c) 
  ->n=1             a -> c
  move(1, b, a, c) 
  ->n=1             b -> c

#縮排代表進行一次遞迴

從上面程式碼中可看出,只要n ≠ 1就會進入遞迴。思想其實很簡單,先將最上面小一點的盤子由a移動到b,再將下面大的盤子由a移動到c,再將b中的小盤子移動到c。

 

有三個盤子的情況:

def move(n, a, b, c):  #n為盤子個數,a為起始位置,b為緩衝區,c為目標位置
    if n == 1:
        print(a +"->"+ c)
    else:
        move(n-1, a, c, b)  #首先需要把 (N-1) 個圓盤移動到 b
        move(1, a, b, c)    #將a的最後一個圓盤移動到c
        move(n-1, b, a, c)  #再將b的(N-1)個圓盤移動到c

move(3, "a", "b", "c")
a->c
a->b
c->b
a->c
b->a
b->c
a->c

解讀程式碼:

move(3, a, b, c)
->n=3 
  move(2, a, c, b) 
  ->n=2
    move(1, a, b, c)
    ->n=1               a -> c
    move(1, a, c, b)
    ->n=1               a -> b
    move(1, c, a, b)
    ->n=1               c -> b

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

  move(2, b, a, c)
  ->n=2
    move(1, b, c, a)
    ->n=1               b -> a
    move(1, b, a, c)
    ->n=1               b -> c
    move(1, a, b, c)
    ->n=1               a -> c

#縮排代表進行一次遞迴,右排為輸出結果

我們的目標就是將a中的盤子,依次全部放到c中。因為有3個盤子,整體的思想就是:

  • 先把a上面2個盤子放到b中,
  • 再把a下面最大的盤子放到c中,
  • 最後將b中的2個盤子放到c中。

通過遞迴的思想,我們進行拆分:

  1. 如何將2個盤子從a放到b,思想還是一樣的。先把上面的小的放到c,再把下面的大的放到b,最後再把c中的放到b。
  2. 把a最下面的盤子放到c。
  3. 如何再從b中2個盤子放到c,一樣的思想。先把上面的小的放到a,再將下面的大的放到c,最後將a中的放到c。

這樣整個過程就結束了。