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;
}
}