课程设计有一个哈夫曼编码解码的题,其他的一般要求还好说~就是最后面有一项用直观的方法输出哈夫曼树。
在网上搜了下,都是用凹凸表之类的在控制台输出,可是感觉还是不直观~
首先我按照遍历的方法,如果不是叶子节点,向左走,找左子树,并画直线,再找右子树,并画直线,一直到叶子节点把节点所代表的字符画上去。但是一开始我每一层画线的角度都是一样的,所以会出现重叠的情况,所以把每一层做一个标记,越向下走,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);
}
}