`
剑晨java
  • 浏览: 23553 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

汉诺塔的可视化

阅读更多
    这是一个迟到了2个月的博客,还真是不好意思,无论做什么都要持之以恒,更何况学习java呢?更要经常学着、做着、总结着。
    我现在要写的是汉诺塔的可视化,就是通过不停画图把汉诺塔的移动过程在画图板上显示出来,当时还不会用别的,想法的也很简单,就是不停的清屏,画圆饼。
    当然遇到的第一个问题就是三个托盘用什么表示,想想汉诺塔圆饼在每个托盘都是从小到大,每次只能取顶部那个圆饼,这不是学过的队列吗?那是还没学集合框架,于是自己写了队列类,定义添加,取得和减少长度的方法。
/**
 * 存储汉诺塔圆片的队列
 * @author 剑晨
 *
 */
public class HanoiQueue {
	/**添加数据的方法*/
	public int[] a=new int[0];
	public void add(int data){
		int []b=new int[a.length+1];
		for(int i=0;i<a.length;i++){
			b[i]=a[i];
		}
		b[a.length]=data;
		a=b;
	}
	/**取出队尾数据的方法*/
	public int get(){
		int num=a[a.length-1];
		return num;
	}
	
	/**数组长度减少的方法*/
	public void cut(){
		int []b=new int[a.length-1];
		for(int i=0;i<a.length-1;i++){
			b[i]=a[i];
		}
		a=b;
	}
}

    第二个问题,就是如何确定圆饼位置和大小,那时还没到对象的程度,没想到把圆饼作为一个个对象,存储着它们位置和大小的信息,只是给每个队列固定的位置,然后是圆饼的大小,首先我要说的是我的队列存的东西,是1234........数字,然后我根据这些数字来确定确定每个圆饼的大小。
/**
	 * 画出圆盘的方法
	 */
	public void draw(){
		Graphics2D g2=(Graphics2D)g;//使用2D画布
		g2.setColor(Color.RED);
		for(int i=0;i<A.a.length;i++){//遍历队列A
			//圆饼位置和大小有队列数字位置和大小确定
			g2.fill3DRect(108- 10 *A.a[i],390-10*i, 20*A.a[i], 10, true);
		}
		for(int i=0;i<B.a.length;i++){//遍历队列B
			g2.fill3DRect(298-10*B.a[i], 390-10*i,20*B.a[i], 10, true);
		}
		for(int i=0;i<C.a.length;i++){//遍历队列C
			g2.fill3DRect(498-10*C.a[i], 390-10*i, 20*C.a[i], 10, true);
		}
	}

   第三个问题就是移动的问题,移动按什么规律呢?开始我想了各种方法始终不行,也想到了递归,可是找不到递归规律。最后求教同学,其实我当时也不太懂,就找了以下,发现这个比较容易懂。
    思路如下:
    首先考虑极限当只有一个盘的时候 只要 盘直接从 a -> b即可
    那么当有2个盘的时候就只要先把1号盘从a -> c 然后 把2号盘 a->b 再 把 2好盘从 c - > b,那么当有n个盘的时候你只要先把 n-1个 盘 借助 b 移动到 c 然后将 n号盘从 a -> b,那么这时候只要将 n-1想办法从c移动到 b 借助 a  那么就可以先把 n-2个盘借助b移动到a,然后 把n-1号盘从c-> b如此递归就是了!
/**
	 * 每次移动的方法
	 * @param X、y 队列
	 */
	public void move(HanoiQueue X,HanoiQueue Y){
		g.clearRect(0, 0, 600, 600);
		draw(g);//调用画托盘的方法
		Y.add(X.get());//队列Y得到队列X队尾数字
		X.cut();//队列X队尾数字去除
		draw();//调用画圆饼的方法
		try{//休眠
			Thread.sleep(1000);
		}catch(Exception of){}
	}
	/**
	 * 递归的方法
	 * @param count 递归深度
	 * @param X 、Y、Z 队列
	 */
	public void hanoi(int count,HanoiQueue X,HanoiQueue Y,HanoiQueue Z){
		if(count==1){
			move(X,Z);
		}else{
         //想想刚刚的思路
			hanoi(count-1,X,Z,Y);
			move(X,Z);
			hanoi(count-1,Y,X,Z);
		}
	}

   这样,基本就算解决了所有难题。以下是我做的效果图。


  • 大小: 6 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics