汉诺塔问题,大一学数据结构的时候就接触了。

今天遇到一个作业,作业要求给定了递归函数的定义:

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

 

这样的话,就不会出问题了。

总结:在递归函数中,参数传递和定义局部变量起的作用是一样的,都是保存本层函数调用的相关数据而已,不会影响其他调用层。而全局变量则会影响其他调用层,然后就乱套了。

 

posted on 2016-06-08 14:59  dcj199411  阅读(373)  评论(0编辑  收藏  举报