汉诺塔问题,大一学数据结构的时候就接触了。
今天遇到一个作业,作业要求给定了递归函数的定义:
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个参数。数据结构书上大概思路是这样子的:
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辅助
}
}
明明就是四个参数!
思考了良久,如何解决那个参数的问题。由于类中有一个成员变量ndisks,于是自己有加了个变量,代码是这个样子的:
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; }
这样的话,就不会出问题了。
总结:在递归函数中,参数传递和定义局部变量起的作用是一样的,都是保存本层函数调用的相关数据而已,不会影响其他调用层。而全局变量则会影响其他调用层,然后就乱套了。