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