3.4问题:
在经典汉诺塔中,有三根柱子以及N个不同大小的穿孔圆盘,盘子可以化入任意一根柱子。一开始,所有 盘子自底向上从大到小一次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时有以下限制:
1、每次只能移动一个盘子;
2、盘子只能从柱子顶端滑出移到下一根柱子;
3、盘子只能叠在比它大的盘子上。
请运用栈,编写程序将所有盘子从第一根柱子移到最后一根柱子。
思想:
很自然的想到递归算法,在每一部分,我们都会执行一下步骤,用伪代码简述如下:
moveDisks(int n,Tower origin,Tower destination,Tower buffer){
/*终止条件*/
if(n<=0) return;
/*将顶端n-1个盘子从origin移至buffer,将destination用作缓冲区*/
moveDisks(n-1,origin,buffer,destination);
/*将origin顶端的盘子移至destination,将origin用作缓冲区。*/
moveDisks(n-1,buffer,destination,origin);
}
详细代码如下:
import java.util.*;
class HLTower{
public static void main(String args[]){
int n =3;
Tower[] towers = new Tower[n];
for(int i =0;i<3;i++){
towers[i]=new Tower(i);
}
for(int i=n-1;i>=0;i--){
towers[0].add(i);
}
towers[0].moveDisks(n,towers[2],towers[1]);
}
}
class Tower{
private Stack<Integer> disks;
private int index;
public Tower(int i){
disks = new Stack<Integer>();
index =i;
}
public int index(){
return index;
}
public void add(int d){
if(!disks.isEmpty()&&disks.peek()<=d){
System.out.println("Error placing disk"+d);
}else{
disks.push(d);
}
}
public void moveTopTo(Tower t){
int top = disks.pop();
t.add(top);
System.out.println("Move disk:"+top+" from tower:"+index()+" to tower:"+t.index());
}
public void moveDisks(int n,Tower destination,Tower buffer){
if(n>0){
moveDisks(n-1,buffer,destination);
moveTopTo(destination);
buffer.moveDisks(n-1,destination,this);
}
}
}