漢諾塔遞歸問題

1.一個函數對於其它函數來講至關於一個盒子,他封裝了其中的內容,其它函數只知道給它參數,而後獲得它的結果。就比如一個作蛋糕的商店:咱們只須要知道給錢,它就會給蛋糕。而咱們不須要理解他們是怎麼作出來的這個蛋糕。函數

2.調用的過程,就至關於上面例子中咱們去買蛋糕的過程。誰說本身不能買本身店裏的蛋糕呢?好比你是作蛋糕的,難道你不能買本身店裏的蛋糕嗎?函數的自我調用(遞歸?)也是這麼回事情。設計

對於hanoi類裏面,兩個核心函數:遞歸

move(char getme, char purone):three

這個函數的功能是:把getme最上面的盤子移動到purone位置,好比 move('A','B')就是把A柱子最上面那個盤子移動到B柱子的最上面。utf-8

hanoi(int n,char one,char two,char three):get

這個函數的功能是:如今在柱子one上一共有n個盤子,這個函數可以經過two把它移動到three上面。 如今你瞭解了這兩個函數設計的初衷,ok,咱們來分別實現每一個函數。數學

public void move(char getme,char purone) {移動

//請聯繫上面寫的這個函數的功能來看: c=c+1;//咱們每移動一步,就計數一次co

System.out.println(getme+"-->"+putone+"搬盤次數爲:"+c); //這行使用輸出來代表移動過了(事實上hanoi就是要讓你詳細說明移動過程,所謂「說明」,就是打印出每次的移動,那這裏咱們就把此次移動打印出來,這個沒有任何問題吧?這個函數就是要把移動這件事情說出來,明白?return

}

public void hanoi(int n,char one,char two,char three) {

//請回憶hanoi函數的功能,是要把one柱子上的前n個放到three柱子上:

if(n==1) //若是n==1,那也就是要把one柱子上最上面的那個移到three上面了,這就是move函數的做用,對吧?那就直接調用

move(one,three) move(one,three);

else{ //若是n>1的話,那咱們該怎麼辦? 分爲三個步驟:

1.先想辦法把one主子上的前n-1個移動到柱子two上

2.而後把one柱子上的第n個移動到柱子three上。

3.而後想辦法把two柱子上的n-1個移動到three上。

對吧?如今你注意到第1步和第3步是否是就是hanoi這個函數的功能可以實現的呢?回答顯然是確定的,下面就是這三步。

hanoi(n-1,one,three,two); //把one柱子上的n-1個經過three移動到two上。

move(one,three); //把one主子上最上面那個(注意,上面一步已經把前n-1個移動到two上面了,one柱如今最上的那個就是第N個)

hanoi(n-1,two,one,three);//把two柱子上的n-1個移動到three柱子上。

}

} 解釋到這裏,main函數裏面的調用應該也就很明白了吧?

a.hanoi(m,'A','B','C'); 把'A'柱子上的m個盤子經過'B'柱子所有移動到'C'上面的步驟。 解釋起來很容易,想得多了也就慢慢明白了,最難的是如何設計一個遞歸出來。這個和數學裏面的遞推公式很類似(事實上其來源就是遞推公式),想必你確定知道遞增函數把?

An = An-1 + 5(A0 = 0 );這個條件可以惟一肯定一個數列。 那如今你把它寫成函數呢?

int A(int n) {

    if(n == 0) {

        return 0;

    } else {

        return A(n -1) + 5;

    }

}

相關文章
相關標籤/搜索