最近无聊,写了一个画二叉树的程序。
- import java.awt.Color;
- import java.awt.Graphics2D;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.PriorityQueue;
- import java.util.Queue;
- import java.util.Stack;
- import javax.imageio.ImageIO;
- publicclass TreeDrawer {
- int totalLevel = 0;
- int leftpadding = Integer.MAX_VALUE;
- publicvoid printTree(TreeNode root, String name) throws IOException{
- totalLevel = getTotalLevel(root) - 1;
- BufferedImage bi = new BufferedImage(1366, 768, BufferedImage.TYPE_INT_BGR);
- Graphics2D g = bi.createGraphics();
- g.setBackground(Color.cyan);
- g.setColor(Color.blue);
- ArrayList q = new ArrayList();
- q.add(root);
- BFSAndPaint(g, q, 0, false);
- bi = new BufferedImage(1366, 768, BufferedImage.TYPE_INT_BGR);
- g = bi.createGraphics();
- BFSAndPaint(g, q, 0, true);
- ImageIO.write(bi, "png", new File(name + ".png"));
- this.leftpadding = Integer.MAX_VALUE;
- }
- publicvoid BFSAndPaint(Graphics2D g, ArrayList l, int level, boolean repaint){
- ArrayList buff = new ArrayList();
- for(int i = 0; i < lsizeispan>
- TreeNode current = l.get(i);
- GraphicNode gnode = null;
- if(null != current){
- gnode = new GraphicNode(level, i, totalLevel);
- int gnodeX = gnode.getPoint(repaint).x;
- int gnodeY = gnode.getPoint(repaint).y;
- g.drawString(current.node + "", gnodeX, gnodeY);
- if(gnodeX < leftpaddingrepaintspan>
- leftpadding = gnodeX;
- }
- if(null != current.left){
- int leftIndex = i * 2;
- GraphicNode gnode_left = new GraphicNode(level + 1, leftIndex, totalLevel);
- g.drawLine(gnodeX + 5, gnodeY, gnode_left.getPoint(repaint).x + 5, gnode_left.getPoint(repaint).y - 10);
- }
- buff.add(current.left);
- if(null != current.right){
- int rightIndex = i * 2 + 1;
- GraphicNode gnode_right = new GraphicNode(level + 1, rightIndex, totalLevel);
- g.drawLine(gnodeX + 5, gnodeY, gnode_right.getPoint(repaint).x + 5, gnode_right.getPoint(repaint).y - 10);
- }
- buff.add(current.right);
- }else{
- buff.add(null);
- buff.add(null);
- }
- }
- if(isBuffEmpty(buff)){
- return;
- }else{
- BFSAndPaint(g, buff, level + 1, repaint);
- }
- }
- publicstaticvoid main(String args []) throws IOException{
- TreeDrawer drawer = new TreeDrawer();
- drawer.run();
- }
- privatevoid run() throws IOException{
- TreeNode node = new TreeNode((int)(Math.random() * 100));
- this.createBT(node, 0);
- this.printTree(node, "test");
- }
- privatevoid createBT(TreeNode node, int n){
- if(n < 5){
- return;
- }
- boolean hasLeft = Math.random() < 0.2 ? true : false;
- if(hasLeft){
- node.left = new TreeNode((int)(Math.random() * 100));
- createBT(node.left, n + 1);
- }
- boolean hasRight = Math.random() < 0.1 ? true : false;
- if(hasRight){
- node.right = new TreeNode((int)(Math.random() * 100));
- createBT(node.right, n + 1);
- }
- }
- privateboolean isBuffEmpty(List list){
- boolean ret = true;
- for(TreeNode node : list){
- if(null != node)
- ret = false;
- }
- return ret;
- }
- privateint getTotalLevel(TreeNode node){
- if(null == node){
- return0;
- }
- return Math.max(getTotalLevel(node.left), getTotalLevel(node.right)) + 1;
- }
- privateclass GraphicNode{
- private Point p;
- privateint level;
- privateint index;
- publicstaticfinalint LOWEST_PADDING = 20;// padding of lowest level. first level is 0
- publicstaticfinalint LEVEL_PADDING = 30;//padding between levels
- privateint totalLevel;
- public GraphicNode(int level, int index, int totalLevel){ //total level is equal to lowest level
- this.level = level;
- this.index = index;
- this.totalLevel = totalLevel;
- this.p = computeP(this.level, this.index);
- }
- private Point computeP(int level, int index) {
- int x = 0;
- for(int i = this.totalLevel; i <level; i--){
- x += getLevelPadding(i) / 2;
- }
- x += getLevelPadding(level) * index;
- int y = LEVEL_PADDING * (level + 1);
- returnnew Point(x, y);
- }
- public Point getPoint(boolean repaint){
- if(repaint){
- returnnew Point(p.x - leftpadding, p.y);
- }
- return p;
- }
- privateint getLevelPadding(int level){
- return (int) (LOWEST_PADDING * Math.pow(2, this.totalLevel - level));
- }
- }
- privateclass Point{
- int x;
- int y;
- public Point(int x, int y){
- this.x = x;
- this.y = y;
- }
- publicint getX(){
- returnthis.x;
- }
- publicint getY(){
- returnthis.y;
- }
- }
- privateclass TreeNode{
- int node;
- TreeNode left;
- TreeNode right;
- public TreeNode(int n){
- node = n;
- left = null;
- right = null;
- }
- }
- }