Java 如何打印二叉树图?
如何用java打印二叉树,以便输出如下:Java 如何打印二叉树图?,java,formatting,binary-tree,Java,Formatting,Binary Tree,如何用java打印二叉树,以便输出如下: cat /\ cat1 cat2 值可以是多个字符。我通常使用中的点程序来实现这一点。有一个简单的例子。这样,您就不必担心间距或字体宽度 cat /\ cat1 cat2 二叉树由 根节点 左子树 右子树 要打印这样一棵树,我们需要打印左子树和右子树(至少有一个空格),然后打印其上的根节点,位于两个子树的中间,并用ASCII线连接。要使其工作,我们需要知道两个子树的宽度 使用这些想法和递
cat
/\
cat1 cat2
值可以是多个字符。我通常使用中的点程序来实现这一点。有一个简单的例子。这样,您就不必担心间距或字体宽度
cat
/\
cat1 cat2
二叉树由
- 根节点
- 左子树
- 右子树
以下是可能有用的方法规范:
/**
* creates an ASCII-drawing of a binary tree.
* @param node the root node of the tree in question
* @return a String[] of the individual lines of the drawing.
* The first line contains the representation of the root node,
* the last line only leaf nodes, interim lines may contain
* line drawing characters or interior nodes.
*
* All the contained strings have the same length (are padded
* with spaces, where necessary).
*/
String[] drawTree(Node node) {
...
}
要输出树,您只需执行以下操作:
for(String line : drawTree(root)) {
System.out.println(line);
}
那么,我们如何实现我们的drawTree
方法呢
- 它对叶节点(即没有子节点的节点)有什么作用
- 如果我们有一个非叶节点,我们如何将两个这样的调用(对于左子树和右子树)的结果(即指定的两个字符串数组)组合到另一个字符串数组(如上所述)?(首先看一看两个数组具有相同长度的简单情况,即树具有相同的深度。)
祝你好运 这里是一个完整的、可运行的演示,它是Scala代码的快速翻译,因此不是惯用Java 有两种实现,一种是获取一棵树并从中生成一个JTree,另一种是使用drawString并使树适合JFrame大小
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.JTree;
/**
(c) GPLv3 2010-09-24
*/
class MNode {
MNode l; // left
MNode r; // right
int t; // value
public MNode (int t, MNode l, MNode r) {
this.l = l;
this.r = r;
this.t = t;
}
public void add (MNode mn) {
if (l == null && t > mn.t)
l = mn;
else if (t > mn.t)
l.add (mn);
else if (r == null)
r = mn;
else r.add (mn);
}
}
abstract class NodePrinter {
abstract void nodeprint (MNode root);
int max (int a, int b) { return (a > b) ? a : b; }
int depth (MNode n)
{
if (n.l == null && n.r == null) return 1;
if (n.l == null) return 1 + depth (n.r);
if (n.r == null) return 1 + depth (n.l);
return 1 + max (depth (n.l), depth (n.r));
}
}
class SwingPrinter extends NodePrinter {
void nodeprint (MNode root) {
JFrame jf = new JFrame ("Mein Freund, der Baum, ist tot");
jf.setSize (380, 380);
jf.setLocationRelativeTo (null);
JTree jt = new JTree (translate2SwingTree (root));
jf.add (jt);
openSubnodes (0, jt);
jf.setDefaultCloseOperation (WindowConstants.DISPOSE_ON_CLOSE);
jf.setVisible (true);
}
/**
Open current branch.
We need TreePath AND row.
Open the MNode, iterierate with the row one step, and check there,
whether the Branch is a part of the new branch.
@param row the row of the starting MNode.
*/
void openSubnodes (int row, JTree jt) {
TreePath tp = jt.getPathForRow (row);
jt.expandRow (row);
if (tp.isDescendant (jt.getPathForRow (row + 1)))
openSubnodes (row + 1, jt);
}
DefaultMutableTreeNode translate2SwingTree (MNode ast)
{
DefaultMutableTreeNode dmtn = new DefaultMutableTreeNode ("" + ast.t);
if (ast.l != null)
dmtn.add (translate2SwingTree (ast.l));
if (ast.r != null)
dmtn.add (translate2SwingTree (ast.r));
return dmtn;
}
}
class TreeCanvas extends JPanel {
private MNode root;
private NodePrinter np;
public TreeCanvas (MNode root, NodePrinter np) {
this.root = root;
this.np = np;
d = np.depth (root);
rows = (2 * d); // - 1
cols = 2 << d;
}
private int d;
private int rows;
private int cols;
// @override
public void paint (Graphics g) {
Dimension dim = getSize ();
int xf = dim.width / cols;
int yf = dim.height / rows;
int fontsize = (xf + yf) / 2;
g.setFont (g.getFont().deriveFont (fontsize* 1.5f));
xyPrint (root, dim.width/2, dim.width/2, 1, xf, yf, g);
}
/**
___50 60 70__________________
10 | x0 x0-x1: (50,30) - (60, 10)
20 | / \ x0-x2: (60,10) - (70, 30)
30 | x1 x2
*/
void xyPrint (MNode n, int x, int dx, int y, int xf, int yf, Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke (new BasicStroke (3.0f));
g.drawString ("" + n.t, x - xf, (y+1) * yf);
g.setColor (Color.BLACK);
if (n.l != null) {
g.drawLine (x - (dx/2) + xf, (y+2) * yf, x, (y+1) * yf); // line:Up
xyPrint (n.l, x - dx/2, dx/2, y + 2, xf, yf, g);
}
if (n.r != null) {
g.drawLine (x + xf, (y+1) * yf, x + (dx/2), (y+2) * yf); // line down
xyPrint (n.r, x + dx/2, dx/2, y + 2, xf, yf, g);
}
}
}
class ColorSwingPrinter extends NodePrinter {
void nodeprint (MNode root) {
JFrame jf = new JFrame ("Rootnode");
jf.setSize (650, 520);
jf.setLocationRelativeTo (null);
jf.add (new TreeCanvas (root, this));
jf.setDefaultCloseOperation (WindowConstants.DISPOSE_ON_CLOSE);
jf.setVisible (true);
}
}
class RootNode extends MNode {
public RootNode (String s)
{
super (Integer.parseInt ("" + s.charAt (0)), null, null);
for (String elem: s.substring (2).split (" "))
{
int i = Integer.parseInt (elem);
MNode mn = new MNode (i, null, null);
super.add (mn);
}
}
}
public class NodePrinterTest {
public static void main (String [] args)
{
String param = "6 7 4 3 8 2 9 5";
/* 6
4 7
3 5 8
2 9
*/
RootNode root = new RootNode (param);
ColorSwingPrinter printer = new ColorSwingPrinter ();
printer.nodeprint (root);
SwingPrinter printer2 = new SwingPrinter ();
printer2.nodeprint (root);
}
}
import java.awt.*;
导入javax.swing.*;
导入javax.swing.tree.*;
导入javax.swing.JTree;
/**
(c) GPLv3 2010-09-24
*/
类MNode{
mnodel;//左
mnoder;//对
int t;//值
公共MNode(int t、MNode l、MNode r){
这个。l=l;
这个。r=r;
t=t;
}
公共无效添加(MNode mn){
if(l==null&&t>mn.t)
l=mn;
否则如果(t>mn.t)
l、 加(mn);
else if(r==null)
r=mn;
否则r.add(mn);
}
}
抽象类NodePrinter{
抽象void nodeprint(MNode root);
intmax(inta,intb){返回(a>b)?a:b;}
整数深度(MNode n)
{
if(n.l==null&&n.r==null)返回1;
如果(n.l==null)返回1+深度(n.r);
如果(n.r==null),则返回1+深度(n.l);
返回1+最大值(深度(n.l)、深度(n.r));
}
}
类SwingPrinter扩展了NodePrinter{
void nodeprint(MNode根){
JFrame jf=新JFrame(“我的弗劳德,德鲍姆,我的托特”);
jf.setSize(380380);
jf.setLocationRelativeTo(空);
JTree jt=新的JTree(translate2SwingTree(root));
jf.add(jt);
开放子节点(0,jt);
jf.setDefaultCloseOperation(WindowConstants.DISPOSE\u ON\u CLOSE);
jf.setVisible(真);
}
/**
打开当前分支。
我们需要树路和路。
打开MNode,一步一行,然后在那里检查,
分支是否为新分支的一部分。
@param row起始MNode的行。
*/
无效开放子节点(int行,JTree jt){
树路径tp=jt.getPathForRow(行);
jt.expandRow(row);
if(tp.isDescendant(jt.getPathForRow(第+1行)))
开放子节点(行+1,jt);
}
DefaultMutableTreeNodeTranslate2SwingTree(MNode ast)
{
DefaultMutableTreeNode dmtn=新的DefaultMutableTreeNode(“+ast.t”);
如果(ast.l!=null)
dmtn.add(translate2SwingTree(ast.l));
如果(ast.r!=null)
dmtn.add(translate2SwingTree(ast.r));
返回dmtn;
}
}
类TreeCanvas扩展了JPanel{
私有MNode根;
私有节点间np;
公共TreeCanvas(mnoderoot,nodeprenternp){
this.root=根;
this.np=np;
d=np.深度(根);
行=(2*d);//-1
cols=2