如何直观形象地树状打印一棵二叉树?
网上绝大部分的二叉树打印效果都十分潦草,也不够直观形象,最近自己用JS写了个图形化小工具
BinaryTreeGraph
,也用Java写了个打印器BinaryTreePrinter
,还有个Objective-C版本BinaryTreePrinterOC
。
具体代码实现请看github。
BinaryTreeGraph(JS版)
- 在线演示:BinaryTreeGraph

二叉树

二叉搜索树

AVL树

红黑树

二叉堆
BinaryTreePrinter(Java版)
简介
- 树状打印一棵二叉树
- 比如输入一棵二叉搜索树
- [381, 12, 410, 9, 40, 394, 540, 35, 190, 476, 760, 146, 445, 600, 800]
- 就会输出

- 或者输出

核心API
public final class BinaryTrees { // 打印一棵二叉树 public static void print(BinaryTreeInfo tree); public static void print(BinaryTreeInfo tree, PrintStyle style); // 打印一棵二叉树(打印完自动换行) public static void println(BinaryTreeInfo tree); public static void println(BinaryTreeInfo tree, PrintStyle style); // 获得一棵二叉树的打印字符串 public static String printString(BinaryTreeInfo tree); public static String printString(BinaryTreeInfo tree, PrintStyle style); // 可选的打印样式 public enum PrintStyle { LEVEL_ORDER, INORDER } }
示例
实现BinaryTreeInfo
- 根节点是谁?
- 如何查找左节点?
- 如何查找右节点?
- 如何打印单个节点?
/** * BinarySearchTree是你自己编写的二叉树类 */ public class BinarySearchTree<E> implements BinaryTreeInfo { /**这里省略了大量代码,只贴出了脉络代码**/ private Node<E> root; private static class Node<E> { E element; Node<E> left; Node<E> right; } /********** BinaryTreeInfo **********/ @Override public Object root() { // 根节点是谁? return root; } @Override public Object left(Object node) { // 如何查找左节点? return ((Node<E>) node).left; } @Override public Object right(Object node) { // 如何查找右节点? return ((Node<E>) node).right; } @Override public Object string(Object node) { // 如何打印单个节点? return ((Node<E>) node).element; } /********** BinaryTreeInfo **********/ }
打印
// 随机生成的一棵二叉搜索树(random generation) BinarySearchTree<Integer> bst = ...; // PrintStyle.LEVEL_ORDER(层序打印) BinaryTrees.println(bst); // PrintStyle.INORDER(中序打印) BinaryTrees.println(bst, PrintStyle.INORDER);

PrintStyle.LEVEL_ORDER

PrintStyle.INORDER
生成字符串写入文件
Files.writeToFile("F:/test/bst.txt", BinaryTrees.printString(bst));
不需要定义二叉树类
BinaryTrees.println(new BinaryTreeInfo() { @Override public Object root() { return 8; } @Override public Object left(Object node) { if (node.equals(8)) return 3; if (node.equals(3)) return 1; if (node.equals(6)) return 4; if (node.equals(14)) return 13; return null; } @Override public Object right(Object node) { if (node.equals(8)) return 10; if (node.equals(10)) return 14; if (node.equals(3)) return 6; if (node.equals(6)) return 7; return null; } @Override public Object string(Object node) { return node; } }); BinaryTrees.println(new BinaryTreeInfo() { @Override public Object root() { return "Life"; } @Override public Object left(Object node) { if (node.equals("Life")) return "Animal"; if (node.equals("Person")) return "Man"; if (node.equals("Animal")) return "Cat"; if (node.equals("Dog")) return "Teddy"; return null; } @Override public Object right(Object node) { if (node.equals("Life")) return "Person"; if (node.equals("Person")) return "Woman"; if (node.equals("Animal")) return "Dog"; if (node.equals("Dog")) return "SingleDog"; return null; } @Override public Object string(Object node) { return node; } });


二叉堆
public class BinaryHeap<E> implements BinaryTreeInfo { private int size; private E[] elements; @Override public Object root() { return 0; } @Override public Object left(Object node) { int index = ((int) node << 1) + 1; return index >= size ? null : index; } @Override public Object right(Object node) { int index = ((int) node << 1) + 2; return index >= size ? null : index; } @Override public Object string(Object node) { return elements[(int) node]; } } BinaryHeap<Integer> heap = new BinaryHeap<>(); for (int i = 0; i < 10; i++) { heap.add((int) (Math.random() * 100)); } BinaryTrees.println(heap);

BinaryTreePrinterOC
- 实现
MJBinaryTreeInfo
协议
@interface MJBSTNode : NSObject { @public id _element; MJBSTNode *_left; MJBSTNode *_right; } @end @interface MJBinarySearchTree : NSObject <MJBinaryTreeInfo> @end @interface MJBinarySearchTree() { MJBSTNode *_root; } @end @implementation MJBinarySearchTree #pragma mark - MJBinaryTreeInfo - (id)left:(MJBSTNode *)node { return node->_left; } - (id)right:(MJBSTNode *)node { return node->_right; } - (id)string:(MJBSTNode *)node { return node->_element; } - (id)root { return _root; } @end
- 打印
[MJBinaryTrees println:bst]; [MJBinaryTrees println:bst style:MJPrintStyleLevelOrder]; [MJBinaryTrees println:bst style:MJPrintStyleInorder]; NSString *str = [MJBinaryTrees printString:bst]; NSString *file = @"/Users/mj/Desktop/1.txt"; [str writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:nil];
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构