画二叉树 java实现

最近无聊,写了一个画二叉树的程序。
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;

public class TreeDrawer {
	int totalLevel = 0;
	int leftpadding = Integer.MAX_VALUE;
	public void 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;
	}
	
	public void BFSAndPaint(Graphics2D g, ArrayList l, int level, boolean repaint){
		ArrayList buff = new ArrayList();
		for(int i = 0; i < l.size(); i++){
			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 < leftpadding && !repaint){
					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);
		}
	}
	
	public static void main(String args []) throws IOException{
		TreeDrawer drawer = new TreeDrawer();
		drawer.run();
	}
	
	private void run() throws IOException{
		TreeNode node = new TreeNode((int)(Math.random() * 100));
		this.createBT(node, 0);
		this.printTree(node, "test");
	}
	
	private void 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);
		}
	}
	
	private boolean isBuffEmpty(List list){
		boolean ret = true;
		for(TreeNode node : list){
			if(null != node)
				ret = false;
		}
		return ret;
	}
	
	private int getTotalLevel(TreeNode node){
		if(null == node){
			return 0;
		}
		return Math.max(getTotalLevel(node.left), getTotalLevel(node.right)) + 1;
	}
	
	private class GraphicNode{
		private Point p;
		private int level;
		private int index;
		public static final int LOWEST_PADDING = 20;// padding of lowest level. first level is 0
		public static final int LEVEL_PADDING = 30;//padding between levels
		private int 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);
			return new Point(x, y);
		}

		public Point getPoint(boolean repaint){
			if(repaint){
				return new Point(p.x - leftpadding, p.y);
			}
			return p;
		}
		
		private int getLevelPadding(int level){
			return (int) (LOWEST_PADDING * Math.pow(2, this.totalLevel - level));
		}
	}
	
	private class Point{
		int x;
		int y;
		
		public Point(int x, int y){
			this.x = x;
			this.y = y;
		}
		
		public int getX(){
			return this.x;
		}
		
		public int getY(){
			return this.y;
		}
	}
	
	private class TreeNode{
		int node;
		TreeNode left;
		TreeNode right;
		public TreeNode(int n){
			node = n;
			left = null;
			right = null;
		}
	}
}

你可能感兴趣的:(编程语言)