漢諾塔問題,大一學數據結構的時候就接觸了。算法
今天遇到一個做業,做業要求給定了遞歸函數的定義:數據結構
public class Tower { private int ndisks; private ArrayList<TowerMove> result = new ArrayList<>(); public Tower(int ndisks) { this.ndisks = ndisks; } public ArrayList<TowerMove> solveTower(String src, String aux, String dst){ return result; }
要實現這個方法,src表示from塔,aux表示輔助塔,dst表示目標塔,三個參數都很熟悉。但是仍是少了一個參數哎,int disk參數沒給啊?函數
網上不少算法包括本身學的數據結構書上的這個遞歸函數都是4個參數。數據結構書上大概思路是這樣子的:this
void hanoi(int n, String src, String aux, String dst){ if(n == 1){ move(1, src, dst); } else{ hanoi(n-1, src, dst, aux); //將 編號爲1~(n-1)的圓盤從src塔移到aux塔,dst輔助
move(n, src, aux, dst); //將最下邊的盤子移到dst
hanoi(n-1, aux, src, dst); //將編號爲1~(n-1)的圓盤從aux塔移到dst,src輔助
} }
明明就是四個參數!spa
思考了良久,如何解決那個參數的問題。因爲類中有一個成員變量ndisks,因而本身有加了個變量,代碼是這個樣子的:code
public ArrayList<TowerMove> solveTower(String src, String aux, String dst){ if(ndisks == 1){ TowerMove move = new TowerMove(1, src, dst); result.add(move); } else{ int temp = ndisks; //保存當前盤子數量到temp變量中 //下面兩行代碼其實等價於 //hanoi(n-1, src, dst, aux); 由於 ndisks--以後遞歸出口用ndisks==1作判斷的 ndisks--; solveTower(src, dst, aux); //遞歸許久以後,該走這裏了,temp仍是本層調用的那個temp //等價於: move(n, src,dst); TowerMove move = new TowerMove(temp, src, dst); result.add(move); //保存移動記錄 //下面兩行代碼其實等價於 //hanoi(n-1, aux, src, dst); ndisks = temp-1; solveTower(aux, src, dst); } return result; }
這樣的話,就不會出問題了。blog
總結:在遞歸函數中,參數傳遞和定義局部變量起的做用是同樣的,都是保存本層函數調用的相關數據而已,不會影響其餘調用層。而全局變量則會影響其餘調用層,而後就亂套了。遞歸