`
jcs130
  • 浏览: 129869 次
  • 性别: Icon_minigender_1
  • 来自: Ottawa
社区版块
存档分类
最新评论

我就是喜欢界面~~可视化打印哈弗曼树(二叉树)~JAVA实现

 
阅读更多

课程设计有一个哈夫曼编码解码的题,其他的一般要求还好说~就是最后面有一项用直观的方法输出哈夫曼树。

在网上搜了下,都是用凹凸表之类的在控制台输出,可是感觉还是不直观~

 

首先我按照遍历的方法,如果不是叶子节点,向左走,找左子树,并画直线,再找右子树,并画直线,一直到叶子节点把节点所代表的字符画上去。但是一开始我每一层画线的角度都是一样的,所以会出现重叠的情况,所以把每一层做一个标记,越向下走,X的值变化得越慢,Y值变化的越快,这样就不会出现重叠的问题了。

 

另外由于直接在窗体上划线在窗体重绘的时候线就会消失,所以就写了个窗体类继承了JFrame并重写了paint()方法,使每一次重绘的时候都能把我画的哈夫曼树画出来。

这是我画出来的哈夫曼树,层数不多,要是层数多的话再修改一下每层X和Y的变化值就可以了~


希望能对和我遇到同样问题的童鞋有所帮助~~哈~~

 

 

 

 

 

具体代码如下~

 

 

package 哈夫曼压缩;

import java.awt.Color;
import java.awt.Graphics;

/**
 * 形状抽象类,所有的形状都必须继承的类
 * @author Micro
 *
 */
public abstract class Shape {
	
	private Color c;//颜色
	
	
	public void setColor(Color c){
		this.c = c;
	}
	
	public Color getColor(){
		return c;
	}
	/**
	 * 绘制的方法
	 * @param g
	 */
	public abstract void draw(Graphics g);

}
 

 

package 哈夫曼压缩;

import java.awt.Graphics;
/**
 * 在界面上画一个字符
 * @author Micro
 *
 */
public class Word extends Shape {
	char c;
	int x;
	int y;

	public Word(char c, int x, int y) {
		this.c = c;
		this.x = x;
		this.y = y;
	}

	@Override
	public void draw(Graphics g) {
		// TODO Auto-generated method stub
		g.setColor(this.getColor());
		g.drawString("" + c, x-5, y+10);
	}

}
 

 

 

package 哈夫曼压缩;

import java.awt.Graphics;

/**
 * 直线类,继承Shape
 * 
 * @author Micro
 * 
 */
public class Line extends Shape {

	private int x1, y1, x2, y2;

	public Line(int x1, int y1, int x2, int y2) {
		this.x1 = x1;
		this.y1 = y1;
		this.x2 = x2;
		this.y2 = y2;
	}

	public void draw(Graphics g) {
		// /设置画布颜色
		g.setColor(this.getColor());
		g.drawLine(x1, y1, x2, y2);
	}

}
 

 

package 哈夫曼压缩;

import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.JFrame;

/**
 * 重写了paint()方法的界面类
 * 
 * @author Micro
 * 
 */
public class MyWindow extends JFrame {

	// 储存所画的图形的列表
	ArrayList<Shape> shapes = new ArrayList<Shape>();

	public ArrayList<Shape> getShapes() {
		return shapes;
	}

	// 重写父类绘制窗体的方法
	public void paint(Graphics g) {
		super.paint(g);
		// 将队列中的形状取出来绘制
		for (int i = 0; i < shapes.size(); i++) {
			// 根据下标取出一个形状对象
			Shape sh = shapes.get(i);
			// 绘制
			sh.draw(g);
		}
	}

}
 

 

 

 

 

 

	// 打印哈夫曼树
	public void printTree(HafNode root) {
		MyWindow jf = new MyWindow();
		jf.setSize(800, 800);
		jf.setVisible(true);
		jf.setDefaultCloseOperation(3);
		drawTree(root, jf, 300, 150, 1);
	}

	// 画哈夫曼树
	public void drawTree(HafNode a, MyWindow jf, int x, int y, int level) {
		Graphics g = jf.getGraphics();
		level++;
		if (a.getLeft() == null && a.getRight() == null) {
			g.drawString("" + a.getN(), x, y);
			jf.getShapes().add(new Word(a.getN(), x, y));
			System.out.println("画完节点" + a.getN());
		}
		if (a.getLeft() != null) {
			g.drawLine(x, y, x - 150/level, y + 10*level);
			jf.getShapes().add(new Line(x, y, x - 150/level, y + 10*level));
			drawTree(a.getLeft(), jf, x - 150/level, y + 10*level, level);
		}
		if (a.getRight() != null) {
			g.drawLine(x, y, x + 150/level, y + 10*level);
			jf.getShapes().add(new Line(x, y, x + 150/level, y + 10*level));
			drawTree(a.getRight(), jf, x + 150/level, y + 10*level, level);
		}
	}
  • 大小: 16.6 KB
1
3
分享到:
评论
2 楼 jcs130 2012-07-10  
ffdqlff 写道
不错.也可以遍历一次,把x,y求出来,然后所有线条都是用这个x,y,会美观一点,不过会比较麻烦

那个……表示没有看懂……您是说先把xy存起来再一起画么?
1 楼 ffdqlff 2012-07-09  
不错.也可以遍历一次,把x,y求出来,然后所有线条都是用这个x,y,会美观一点,不过会比较麻烦

相关推荐

Global site tag (gtag.js) - Google Analytics