汉诺塔问题[又称河内塔]是印度的一个古老的传说。

据传开天辟地之神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金 片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次 只能搬一个,而且大的不能放在小的上面。就是这看似简单的问题,却困扰了人们千年以上。

后来,这个传说就演变为汉诺塔游戏,玩法如下:

1.有三根杆子A,B,C。A杆上有若干碟子 
2.每次移动一块碟子,小的只能叠在大的上面 
3.把所有碟子从A杆全部移到C杆上

经过研究发现,三圆盘的汉诺塔问题很好破解,就是按照移动规则向一个方向移动金片:
如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C

但每当增加一阶,移动的次数却会以倍数增加,因此每当圆盘增加到一定数量时,常人只能望而却步。

而我们程序员却可以借助于计算机的运算性能,轻而易举地解决这一问题,汉诺塔问题也作为程序设计中的经典递归问题而存在下来。

但是,实践和理论往往却有天壤之别,我们虽然可以运算出汉诺塔的结果,但是却未必能动手完成这一结果。不信?我这里给出了一个简单的汉诺塔实现,有兴趣的可以自己码盘子看看。

java汉诺塔测试_javapackage org.loon.test;
java汉诺塔测试_java
java汉诺塔测试_java
import java.awt.Color;
java汉诺塔测试_java
import java.awt.Dimension;
java汉诺塔测试_java
import java.awt.Frame;
java汉诺塔测试_java
import java.awt.Graphics;
java汉诺塔测试_java
import java.awt.Menu;
java汉诺塔测试_java
import java.awt.MenuBar;
java汉诺塔测试_java
import java.awt.MenuItem;
java汉诺塔测试_java
import java.awt.event.ActionEvent;
java汉诺塔测试_java
import java.awt.event.ActionListener;
java汉诺塔测试_java
import java.awt.event.MouseAdapter;
java汉诺塔测试_java
import java.awt.event.MouseEvent;
java汉诺塔测试_java
import java.awt.event.WindowAdapter;
java汉诺塔测试_java
import java.awt.event.WindowEvent;
java汉诺塔测试_java
java汉诺塔测试_测试_17
/**
java汉诺塔测试_测试_19 * <p>
java汉诺塔测试_测试_19 * Title: LoonFramework
java汉诺塔测试_测试_19 * </p>
java汉诺塔测试_测试_19 * <p>
java汉诺塔测试_测试_19 * Description:java汉诺塔测试
java汉诺塔测试_测试_19 * </p>
java汉诺塔测试_测试_19 * <p>
java汉诺塔测试_测试_19 * Copyright: Copyright (c) 2007
java汉诺塔测试_测试_19 * </p>
java汉诺塔测试_测试_19 * <p>
java汉诺塔测试_测试_19 * Company: LoonFramework
java汉诺塔测试_测试_19 * </p>
java汉诺塔测试_测试_19 * 
java汉诺塔测试_测试_19 * 
@author chenpeng
java汉诺塔测试_测试_19 * @email:[email]ceponline@yahoo.com.cn[/email]
java汉诺塔测试_测试_19 * 
@version 0.1
java汉诺塔测试_汉诺塔_35 
*/

java汉诺塔测试_测试_36
public class Hanio extends Frame {
java汉诺塔测试_职场_38    
/**
java汉诺塔测试_测试_19     * 
java汉诺塔测试_测试_41     
*/

java汉诺塔测试_测试_19    
private static final long serialVersionUID = 1L;
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19    
private HanioDraw _hanioDraw;
java汉诺塔测试_测试_19
java汉诺塔测试_职场_46    
public static void main(String args[]) {
java汉诺塔测试_测试_19        
new Hanio("java汉诺塔实现测试"350300);
java汉诺塔测试_测试_41    }

java汉诺塔测试_测试_19
java汉诺塔测试_java_51    
public Hanio(String string, int width, int height) {
java汉诺塔测试_测试_19        
super(string);
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        _hanioDraw 
= new HanioDraw();
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        setResizable(
false);// 设为用户不可改变窗体大小
java汉诺塔测试_测试_19
        setSize(width, height);// 设置窗口大小
java汉诺塔测试_测试_19
        setBackground(Color.WHITE);// 背景颜色设置为白色
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        
// 菜单
java汉诺塔测试_测试_19
        MenuBar myMenu = new MenuBar();
java汉诺塔测试_测试_19        Menu sMenu 
= new Menu("选择数量");
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        MenuItem[] mItems 
= new MenuItem[6];
java汉诺塔测试_职场_66        
for (int i = 3; i <= 8; i++{
java汉诺塔测试_测试_19            mItems[i 
- 3= new MenuItem(String.valueOf(i));
java汉诺塔测试_汉诺塔_69            mItems[i 
- 3].addActionListener(new ActionListener() {
java汉诺塔测试_休闲_71                
public void actionPerformed(ActionEvent e) {
java汉诺塔测试_测试_19                    _hanioDraw.init(Integer.parseInt(((MenuItem) e.getSource())
java汉诺塔测试_测试_19                            .getLabel().toString()));
java汉诺塔测试_测试_19                    repaint();
java汉诺塔测试_测试_41                }

java汉诺塔测试_测试_41            }
);
java汉诺塔测试_测试_19            sMenu.add(mItems[i 
- 3]);
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        myMenu.add(sMenu);
java汉诺塔测试_测试_19        setMenuBar(myMenu);
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        setLayout(
null);
java汉诺塔测试_测试_19        
// 加入窗体监听
java汉诺塔测试_测试_86
        addWindowListener(new WindowAdapter() {
java汉诺塔测试_汉诺塔_88            
public void windowClosing(WindowEvent e) {
java汉诺塔测试_测试_19                System.exit(
0);
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_41        }
);
java汉诺塔测试_测试_19        
// 加入鼠标监听
java汉诺塔测试_汉诺塔_94
        addMouseListener(new MouseAdapter() {
java汉诺塔测试_休闲_96            
public void mouseClicked(MouseEvent e) {
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19                Hanio hanio 
= (Hanio) e.getSource();
java汉诺塔测试_测试_19                Dimension frSize 
= hanio.getSize();
java汉诺塔测试_测试_19                
int x = e.getX();
java汉诺塔测试_测试_19                
int w = frSize.width / 3;
java汉诺塔测试_休闲_103                
if (x < w) {
java汉诺塔测试_测试_19                    hanio.getHanioDraw().click(
0);
java汉诺塔测试_职场_106                }
 else if (x < (2 * w)) {
java汉诺塔测试_测试_19                    hanio.getHanioDraw().click(
1);
java汉诺塔测试_测试_109                }
 else {
java汉诺塔测试_测试_19                    hanio.getHanioDraw().click(
2);
java汉诺塔测试_测试_41                }

java汉诺塔测试_测试_19
java汉诺塔测试_测试_19                hanio.repaint();
java汉诺塔测试_测试_19
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_41        }
);
java汉诺塔测试_测试_19        
// 窗体居中
java汉诺塔测试_测试_19
        setLocationRelativeTo(null);
java汉诺塔测试_测试_19        
// 显示窗口
java汉诺塔测试_测试_19
        setVisible(true);
java汉诺塔测试_测试_19
java汉诺塔测试_测试_41    }

java汉诺塔测试_测试_19
java汉诺塔测试_汉诺塔_125    
public void paint(Graphics g) {
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        
final int OBJECT_H = 15;// 对象高
java汉诺塔测试_测试_19
        final int OBJECT_W = 10;// 对象宽
java汉诺塔测试_测试_19
        final int OBJECT_D = 90;// 对象间距
java汉诺塔测试_测试_19
        final int OBJECT_S = 60;// 起始位置
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        
// 绘制图像
java汉诺塔测试_测试_19
        int n;
java汉诺塔测试_职场_135        
for (n = 0; n < 8; n++{
java汉诺塔测试_java_137            
if (_hanioDraw.getBlock(n, 0!= 0{
java汉诺塔测试_测试_19                g.drawRect(OBJECT_S, 
200 - n * OBJECT_H, OBJECT_W
java汉诺塔测试_测试_19                        
* _hanioDraw.getBlock(n, 0), OBJECT_H);
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_41        }

java汉诺塔测试_java_143        
for (n = 0; n < 8; n++{
java汉诺塔测试_汉诺塔_145            
if (_hanioDraw.getBlock(n, 1!= 0{
java汉诺塔测试_测试_19                g.drawRect(OBJECT_D 
+ OBJECT_S, 200 - n * OBJECT_H, OBJECT_W
java汉诺塔测试_测试_19                        
* _hanioDraw.getBlock(n, 1), OBJECT_H);
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_41        }

java汉诺塔测试_汉诺塔_151        
for (n = 0; n < 8; n++{
java汉诺塔测试_休闲_153            
if (_hanioDraw.getBlock(n, 2!= 0{
java汉诺塔测试_测试_19                g.drawRect(
2 * OBJECT_D + OBJECT_S, 200 - n * OBJECT_H,
java汉诺塔测试_测试_19                        OBJECT_W 
* _hanioDraw.getBlock(n, 2), OBJECT_H);
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_java_160        
if (_hanioDraw.getTop() != 0{
java汉诺塔测试_测试_19            g.drawRect(
6060, OBJECT_W * _hanioDraw.getTop(), OBJECT_H);
java汉诺塔测试_测试_41        }

java汉诺塔测试_java_164        
if (_hanioDraw.goFull()) {
java汉诺塔测试_测试_19            g.drawString(
"完成"100100);
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_测试_41    }

java汉诺塔测试_测试_19
java汉诺塔测试_测试_171    
public HanioDraw getHanioDraw() {
java汉诺塔测试_测试_19        
return _hanioDraw;
java汉诺塔测试_测试_41    }

java汉诺塔测试_测试_19
java汉诺塔测试_休闲_176    
public void setHanioDraw(HanioDraw hd) {
java汉诺塔测试_测试_19        
this._hanioDraw = hd;
java汉诺塔测试_测试_41    }

java汉诺塔测试_测试_19
java汉诺塔测试_休闲_181    
class HanioDraw {
java汉诺塔测试_测试_19
java汉诺塔测试_测试_19        
private int _top;// 拿起的方块
java汉诺塔测试_测试_19

java汉诺塔测试_测试_19        
private int _size;// 总数
java汉诺塔测试_测试_19

java汉诺塔测试_测试_19        
private int[][] _room;// 用以存储位置
java汉诺塔测试_测试_19

java汉诺塔测试_测试_19        
private int[] _cache;// 缓存单个对象
java汉诺塔测试_测试_19

java汉诺塔测试_职场_192        
public HanioDraw() {
java汉诺塔测试_测试_19            _room 
= new int[8][3];
java汉诺塔测试_测试_19            _cache 
= new int[3];
java汉诺塔测试_测试_19            
// 默认初始值
java汉诺塔测试_测试_19
            init(3);
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_休闲_200        
/**
java汉诺塔测试_测试_19         * 开始处理
java汉诺塔测试_测试_19         * 
java汉诺塔测试_测试_19         * 
@param x
java汉诺塔测试_测试_41         
*/

java汉诺塔测试_职场_206        
public void init(int x) {
java汉诺塔测试_测试_19            _size 
= x - 1;
java汉诺塔测试_汉诺塔_209            
for (int i = 0; i <= 2; i++{
java汉诺塔测试_休闲_211                
for (int j = 0; j < 8; j++{
java汉诺塔测试_测试_19                    _room[j][i] 
= 0;
java汉诺塔测试_测试_41                }

java汉诺塔测试_测试_19                _cache[i] 
= -1;
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_217            
for (int i = 0; i < x; ++i) {
java汉诺塔测试_测试_19                _room[i][
0= x - i;
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_19            _cache[
0= x - 1;
java汉诺塔测试_测试_19            _top 
= 0;
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_休闲_225        
/**
java汉诺塔测试_测试_19         * 拿起目标对象
java汉诺塔测试_测试_19         * 
java汉诺塔测试_测试_19         * 
@param x
java汉诺塔测试_测试_19         * 
@return
java汉诺塔测试_测试_41         
*/

java汉诺塔测试_汉诺塔_232        
boolean take(int x) {
java汉诺塔测试_测试_19            
if (_cache[x] == -1)
java汉诺塔测试_测试_19                
return false;
java汉诺塔测试_测试_19            _top 
= _room[_cache[x]][x];
java汉诺塔测试_测试_19            _room[_cache[x]][x] 
= 0;
java汉诺塔测试_测试_19            _cache[x]
--;
java汉诺塔测试_测试_19            
return true;
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_休闲_242        
/**
java汉诺塔测试_测试_19         * 拖动目标对象
java汉诺塔测试_测试_19         * 
java汉诺塔测试_测试_19         * 
@param x
java汉诺塔测试_测试_19         * 
@return
java汉诺塔测试_测试_41         
*/

java汉诺塔测试_汉诺塔_249        
boolean drop(int x) {
java汉诺塔测试_休闲_251            
if (_cache[x] != -1{
java汉诺塔测试_测试_19                
if (_top > _room[_cache[x]][x])
java汉诺塔测试_测试_19                    
return false;
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_19            _cache[x]
++;
java汉诺塔测试_测试_19            _room[_cache[x]][x] 
= _top;
java汉诺塔测试_测试_19            _top 
= 0;
java汉诺塔测试_测试_19            
return true;
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_测试_262        
/**
java汉诺塔测试_测试_19         * 判定事件是否完成
java汉诺塔测试_测试_19         * 
java汉诺塔测试_测试_19         * 
@return
java汉诺塔测试_测试_41         
*/

java汉诺塔测试_java_268        
public boolean goFull() {
java汉诺塔测试_汉诺塔_270            
if (_cache[1== _size) {
java汉诺塔测试_测试_19                
return true;
java汉诺塔测试_测试_41            }

java汉诺塔测试_java_274            
if (_cache[2== _size) {
java汉诺塔测试_测试_19                
return true;
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_19            
return false;
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_休闲_281        
/**
java汉诺塔测试_测试_19         * 点击事件
java汉诺塔测试_测试_19         * 
java汉诺塔测试_测试_19         * 
@param x
java汉诺塔测试_测试_19         * 
@return
java汉诺塔测试_测试_41         
*/

java汉诺塔测试_汉诺塔_288        
public boolean click(int x) {
java汉诺塔测试_汉诺塔_290            
if (goFull()) {
java汉诺塔测试_测试_19                
return false;
java汉诺塔测试_测试_41            }

java汉诺塔测试_汉诺塔_294            
if (_top == 0{
java汉诺塔测试_测试_19                take(x);
java汉诺塔测试_休闲_297            }
 else {
java汉诺塔测试_测试_19                drop(x);
java汉诺塔测试_测试_41            }

java汉诺塔测试_测试_19            
return true;
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_职场_304        
public int getTop() {
java汉诺塔测试_测试_19            
return _top;
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_19
java汉诺塔测试_职场_309        
public int getBlock(int x, int group) {
java汉诺塔测试_测试_19            
return _room[x][group];
java汉诺塔测试_测试_41        }

java汉诺塔测试_测试_41    }

java汉诺塔测试_测试_19
java汉诺塔测试_汉诺塔_35}

java汉诺塔测试_java

运行图如下: