打印二叉树
介绍
二叉树是一种重要的数据结构,在编写程序时,经常需要以可读性较强的方式打印二叉树结构,以便更好地理解和调试代码。
本节将介绍一个简单而有效的二叉树打印工具,以及如何使用该工具。
使用效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Main { public static void main(String[] args) { BinarySerchTree<Integer> bst = new BinarySerchTree<>(); bst.add(new Integer(15)); bst.add(new Integer(7)); bst.add(new Integer(26)); bst.add(new Integer(13)); bst.add(new Integer(40)); bst.add(new Integer(3)); bst.add(new Integer(19)); bst.printTree(); } }
|
运行效果:
工具代码
这个二叉树打印的工具类有两个,分别是 PrintableNode
接口和 TreePrinter
工具类。
PrintableNode 接口
首先,让我们看一下 PrintableNode
接口的定义:
1 2 3 4 5
| public interface PrintableNode { PrintableNode getLeft(); PrintableNode getRight(); String getData(); }
|
该接口定义了三个方法:
getLeft()
: 获取左子节点
getRight()
: 获取右子节点
getData()
: 获取要打印的节点的值
因此,我们自己的节点类必须implements
这个PrintableNode
接口,然后实现这三个方法。
TreePrinter 工具类
现在,我们来看一下 TreePrinter
工具类的代码。
这个工具类提供了一个静态方法 print
,用于打印二叉树结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
| import java.util.ArrayList; import java.util.List;
public class TreePrinter {
public static void print(PrintableNode root) { List<List<String>> lines = new ArrayList<>();
List<PrintableNode> level = new ArrayList<>(); List<PrintableNode> next = new ArrayList<>();
level.add(root); int nn = 1;
int widest = 0;
while (nn != 0) { List<String> line = new ArrayList<>();
nn = 0;
for (PrintableNode n : level) { if (n == null) { line.add(null); next.add(null); next.add(null); } else { String aa = n.getData(); line.add(aa); if (aa.length() > widest) widest = aa.length();
next.add(n.getLeft()); next.add(n.getRight());
if (n.getLeft() != null) nn++; if (n.getRight() != null) nn++; } }
if (widest % 2 == 1) widest++;
lines.add(line);
List<PrintableNode> tmp = level; level = next; next = tmp; next.clear(); }
int perpiece = lines.get(lines.size() - 1).size() * (widest + 4);
for (int i = 0; i < lines.size(); i++) { List<String> line = lines.get(i); int hpw = (int) Math.floor(perpiece / 2f) - 1;
if (i > 0) { for (int j = 0; j < line.size(); j++) {
char c = ' '; if (j % 2 == 1) { if (line.get(j - 1) != null) { c = (line.get(j) != null) ? '┴' : '┘'; } else { if (j < line.size() && line.get(j) != null) c = '└'; } } System.out.print(c);
if (line.get(j) == null) { for (int k = 0; k < perpiece - 1; k++) { System.out.print(" "); } } else {
for (int k = 0; k < hpw; k++) { System.out.print(j % 2 == 0 ? " " : "─"); } System.out.print(j % 2 == 0 ? "┌" : "┐"); for (int k = 0; k < hpw; k++) { System.out.print(j % 2 == 0 ? "─" : " "); } } } System.out.println(); }
for (int j = 0; j < line.size(); j++) {
String f = line.get(j); if (f == null) f = ""; int gap1 = (int) Math.ceil(perpiece / 2f - f.length() / 2f); int gap2 = (int) Math.floor(perpiece / 2f - f.length() / 2f);
for (int k = 0; k < gap1; k++) { System.out.print(" "); } System.out.print(f); for (int k = 0; k < gap2; k++) { System.out.print(" "); } } System.out.println();
perpiece /= 2; } } }
|
如何使用?
现在,我们将演示如何使用 TreePrinter
工具类来打印二叉树。
首先,确保你的二叉树节点实现了 PrintableNode
接口。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class Node<E> implements PrintableNode { E element; Node<E> left; Node<E> right; Node<E> parent; public Node(E element, Node<E> parent) { this.element = element; this.parent = parent; } @Override public PrintableNode getLeft() { return left; }
@Override public PrintableNode getRight() { return right; }
@Override public String getData() { return element.toString(); } }
|
然后,在自己的二叉树类中,声明一个printTree
方法,调用TreePrinter
类的静态方法print
,将根结点root
传进去即可。
1 2 3 4 5 6 7 8 9 10 11
| public class BinarySerchTree<E> { private Node<E> root;
public void printTree() { TreePrinter.print(root); } }
|