假设您的二叉树以下列方式表示:
public class BinaryTreeModel {
private Object value;
private BinaryTreeModel left;
private BinaryTreeModel right;
public BinaryTreeModel(Object value) {
this.value = value;
}
// standard getters and setters
}
那么漂亮打印树的代码可以这样写:
对于根节点:
public String traversePreOrder(BinaryTreeModel root) {
if (root == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append(root.getValue());
String pointerRight = "└──";
String pointerLeft = (root.getRight() != null) ? "├──" : "└──";
traverseNodes(sb, "", pointerLeft, root.getLeft(), root.getRight() != null);
traverseNodes(sb, "", pointerRight, root.getRight(), false);
return sb.toString();
}
对于子节点:
public void traverseNodes(StringBuilder sb, String padding, String pointer, BinaryTreeModel node,
boolean hasRightSibling) {
if (node != null) {
sb.append("\n");
sb.append(padding);
sb.append(pointer);
sb.append(node.getValue());
StringBuilder paddingBuilder = new StringBuilder(padding);
if (hasRightSibling) {
paddingBuilder.append("│ ");
} else {
paddingBuilder.append(" ");
}
String paddingForBoth = paddingBuilder.toString();
String pointerRight = "└──";
String pointerLeft = (node.getRight() != null) ? "├──" : "└──";
traverseNodes(sb, paddingForBoth, pointerLeft, node.getLeft(), node.getRight() != null);
traverseNodes(sb, paddingForBoth, pointerRight, node.getRight(), false);
}
}
那么你需要做的就是像这样调用根节点的函数:
System.out.println(traversePreOrder(root));
本文详细解释了整个方法 - https://www.baeldung.com/java-print-binary-tree-diagram。这个想法可以扩展到漂亮的打印generic trees、tries 等等。
如何为 trie 做同样的事情?
假设 trie 的辅助类是 Trie 和 TrieNode,定义如下:
public class TrieNode{
public HashMap<Character, TrieNode> children;
public boolean isWord;
public TrieNode() {
children = new HashMap<>();
isWord = false;
}
}
和
public class Trie{
public TrieNode root;
public Trie() {
root = new TrieNode();
}
// Insert method for trie, search method for trie, delete method for trie not shown as they are not relevant
}
现在,要实现漂亮的打印方法,只需在 Trie 类中插入这两个方法:
public String traversePreOrder() {
if (root == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append("○");
Set<Character> childNodeChars = root.children.keySet();
Iterator<Character> iterator = childNodeChars.iterator();
while (iterator.hasNext()) {
Character childC = iterator.next();
if (!iterator.hasNext())
traverseNodes(sb, "", "└──", root, childC, false);
else
traverseNodes(sb, "", "├──", root, childC, true);
}
return sb.toString();
}
private void traverseNodes(StringBuilder sb, String padding, String pointer, TrieNode node, Character c, boolean hasNextSibling) {
sb.append("\n");
sb.append(padding);
sb.append(pointer);
sb.append(c);
sb.append(node.children.get(c).isWord?"(1)":"");
StringBuilder paddingBuilder = new StringBuilder(padding);
paddingBuilder.append(hasNextSibling?"│ ":" ");
String paddingForBoth = paddingBuilder.toString();
TrieNode childNode = node.children.get(c);
if(childNode == null)
return;
Set<Character> childNodeChars = childNode.children.keySet();
Iterator<Character> iterator = childNodeChars.iterator();
while (iterator.hasNext()) {
Character childC = iterator.next();
if (!iterator.hasNext())
traverseNodes(sb, paddingForBoth, "└──", childNode, childC, false);
else
traverseNodes(sb, paddingForBoth, "├──", childNode, childC, true);
}
}