汉诺塔问题解决
假设三个柱子称为A,B,C,其中n个圆盘初始时在A,目标是把n个圆盘移到B。
怎么挪,总共分三步:
- 把n-1个圆盘挪到C。
- 把第n个圆盘挪到B。
- 把C上的n-1个挪到B。
其中第一步和第二步是与“把n个圆盘从A挪到B”一样的问题,即“把m个圆盘从A挪到C”,和“把m个圆盘从C挪到B”,所以递归可以解决。
代码设计
定义一个Tower类代表一个柱子,继承java.util.Stack,控制元素先进后出;泛型用Integer,数字越大表示圆盘越大,复写addElement和push方法,控制大的只能在小的下面(下标越小表示越靠下)。
定义一个HannoTower类表示整个系统,包含三个柱子;构造函数参数表示初始化时A有几个圆盘。
HannoTower定义基本操作moveOne,即最基本的动作:从一个柱子上拿出一个放到另一个柱子上。
HannoTower定义public void move(Tower from, Tower to, Tower buffer, Integer quantity),递归方法,从from挪动quantity个圆盘到to,buffer为第三个柱子。
HannoTower定义public void move()为启动方法
public class Tower extends Stack <Integer>{ public Tower(Integer n) { while(n > 0){ this.push(n); n--; } } public Tower() { } @Override public Integer push(Integer item) { this.addElement(item); return item; } @Override public synchronized void addElement(Integer item) { if(super.size() == 0){ super.addElement(item); return; } Integer i = super.firstElement(); if(i <= item){ throw new IllegalArgumentException(item + " is bigger than the last element " + i); } super.addElement(item); } }
public class HannoTower { Tower t1; Tower t2; Tower t3; public HannoTower(Integer n) { this.t1 = new Tower(n); this.t2 = new Tower(); this.t3 = new Tower(); } public void moveOne(Tower from, Tower to){ Integer e = from.pop(); to.push(e); } public void move(Tower from, Tower to, Tower buffer, Integer quantity){ if(quantity == 1){ moveOne(from, to); }else{ move(from, buffer, to, quantity - 1); moveOne(from, to); move(buffer, to, from, quantity - 1); } } public void move(){ move(t1,t2,t3,t1.size()); } public void print(){ System.out.println(t1); System.out.println(t2); System.out.println(t3); } }
public class TowerTest { public static void main(String[] args) { HannoTower tt = new HannoTower(13); System.out.println("起始:"); tt.print(); tt.move(); System.out.println("结束:"); tt.print(); } }
浙公网安备 33010602011771号