在 LeetCode、算法竞赛以及实际工程开发中二叉树Binary Tree是最核心的数据结构之一。很多初学者在刷题时往往只会“调用”二叉树却不真正理解TreeNode 为什么这样设计buildTree 是如何构造树的为什么需要 deleteTree如何优雅地打印一棵树本文将通过一个完整的 C 示例系统讲解二叉树最核心的几个基础模块。一、什么是二叉树Binary Tree二叉树是一种每个节点最多只有两个子节点的数据结构。通常左孩子left右孩子right例如3 / \ 9 20 / \ 15 7这就是一棵典型二叉树。二、TreeNode 节点结构代码struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} };三、TreeNode 的核心组成一个二叉树节点通常包含三部分成员含义val当前节点值left指向左子树right指向右子树即TreeNode ├── val ├── left └── right四、为什么 left 和 right 是指针因为二叉树本质上是“节点之间的连接关系”例如1 / \ 2 3节点 1 需要“指向”节点 2 和节点 3。因此TreeNode* left; TreeNode* right;用于保存子节点地址。五、构造函数详解1. 默认构造TreeNode() : val(0), left(nullptr), right(nullptr) {}生成值为0 左右孩子为空2. 单参数构造TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}例如TreeNode* node new TreeNode(5);结果节点值 5 left nullptr right nullptr3. 完整构造TreeNode(int x, TreeNode *left, TreeNode *right)允许直接创建根节点 左子树 右子树例如TreeNode* root new TreeNode(1, new TreeNode(2), new TreeNode(3));得到1 / \ 2 3六、buildTree如何构建二叉树代码TreeNode* buildTree(vectorint nodes)作用根据层序数组构建二叉树。例如[3,9,20,null,null,15,7]对应3 / \ 9 20 / \ 15 7七、为什么使用队列 queue因为构建过程本质是层序遍历Level Order Traversal需要先处理父节点 再处理子节点这是典型 BFS广度优先搜索思想。因此queueTreeNode* q;用于保存“等待处理”的节点。八、buildTree 核心流程Step 1创建根节点TreeNode* root new TreeNode(nodes[0]);Step 2根节点入队q.push(root);Step 3循环处理队列while (!q.empty())每次取出一个父节点TreeNode* curr q.front(); q.pop();Step 4构建左孩子curr-left new TreeNode(nodes[i]);Step 5构建右孩子curr-right new TreeNode(nodes[i]);九、为什么用 -101 表示 null因为vectorint不能直接存储null所以使用特殊值-101表示空节点。例如[1, -101, 2]表示1 \ 2十、deleteTree为什么必须释放内存代码void deleteTree(TreeNode* root)作用递归释放整棵树。因为new TreeNode(...)是在堆区申请内存。如果不释放会造成内存泄漏Memory Leak十一、deleteTree 为什么使用后序遍历代码deleteTree(root-left); deleteTree(root-right); delete root;顺序左 - 右 - 根原因必须先删除子节点再删除父节点。否则父节点被释放后 无法继续访问孩子节点十二、printTree打印二叉树很多时候调试二叉树非常困难。因此我们通常会实现printTree(root)这里给出一个经典层序打印。printTree 实现void printTree(TreeNode* root) { if (root nullptr) { cout Empty Tree endl; return; } queueTreeNode* q; q.push(root); while (!q.empty()) { int size q.size(); for (int i 0; i size; i) { TreeNode* curr q.front(); q.pop(); if (curr nullptr) { cout null ; continue; } cout curr-val ; q.push(curr-left); q.push(curr-right); } cout endl; } }十三、printTree 输出效果例如vectorint nodes {3,9,20,-101,-101,15,7};打印3 9 20 null null 15 7树结构一目了然。十四、maxDepth求二叉树最大深度代码int maxDepth(TreeNode* root)核心思想当前树高度 max(左子树高度, 右子树高度) 1即return max(leftDepth, rightDepth) 1;十五、递归思想分析例如3 / \ 9 20 / \ 15 7递归会不断向下3 ├── 9 └── 20 ├── 15 └── 7直到root nullptr返回0然后逐层回溯计算高度。十六、时间复杂度分析buildTree每个节点访问一次O(n)deleteTree每个节点删除一次O(n)maxDepth每个节点遍历一次O(n)#include iostream #include vector #include queue #include stack #include algorithm using namespace std; /* TreeNode Definition */ struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {} }; /* Build Binary Tree Level Order Construction */ TreeNode* buildTree(const vectorint nodes, int nullVal -101) { if (nodes.empty() || nodes[0] nullVal) { return nullptr; } TreeNode* root new TreeNode(nodes[0]); queueTreeNode* q; q.push(root); int i 1; while (!q.empty() i nodes.size()) { TreeNode* curr q.front(); q.pop(); // left child if (i nodes.size() nodes[i] ! nullVal) { curr-left new TreeNode(nodes[i]); q.push(curr-left); } i; // right child if (i nodes.size() nodes[i] ! nullVal) { curr-right new TreeNode(nodes[i]); q.push(curr-right); } i; } return root; } /* Delete Binary Tree Postorder Traversal */ void deleteTree(TreeNode* root) { if (root nullptr) { return; } deleteTree(root-left); deleteTree(root-right); delete root; } /* Print Binary Tree Level Order Traversal */ void printTree(TreeNode* root) { if (root nullptr) { cout Empty Tree endl; return; } queueTreeNode* q; q.push(root); while (!q.empty()) { int size q.size(); for (int i 0; i size; i) { TreeNode* curr q.front(); q.pop(); if (curr nullptr) { cout null ; continue; } cout curr-val ; q.push(curr-left); q.push(curr-right); } cout endl; } } /* DFS Traversal */ // preorder void preorder(TreeNode* root) { if (root nullptr) { return; } cout root-val ; preorder(root-left); preorder(root-right); } // inorder void inorder(TreeNode* root) { if (root nullptr) { return; } inorder(root-left); cout root-val ; inorder(root-right); } // postorder void postorder(TreeNode* root) { if (root nullptr) { return; } postorder(root-left); postorder(root-right); cout root-val ; } /* BFS Traversal */ void levelOrder(TreeNode* root) { if (root nullptr) { return; } queueTreeNode* q; q.push(root); while (!q.empty()) { TreeNode* curr q.front(); q.pop(); cout curr-val ; if (curr-left) q.push(curr-left); if (curr-right) q.push(curr-right); } } /* Tree Height */ int maxDepth(TreeNode* root) { if (root nullptr) { return 0; } return max( maxDepth(root-left), maxDepth(root-right) ) 1; } /* Count Nodes */ int countNodes(TreeNode* root) { if (root nullptr) { return 0; } return countNodes(root-left) countNodes(root-right) 1; } /* Search Value */ bool search(TreeNode* root, int target) { if (root nullptr) { return false; } if (root-val target) { return true; } return search(root-left, target) || search(root-right, target); } /* Example Main */ int main() { vectorint nodes { 3, 9, 20, -101, -101, 15, 7 }; TreeNode* root buildTree(nodes); cout Print Tree: endl; printTree(root); cout endl; cout Preorder: ; preorder(root); cout endl; cout Inorder: ; inorder(root); cout endl; cout Postorder: ; postorder(root); cout endl; cout LevelOrder: ; levelOrder(root); cout endl; cout MaxDepth: ; cout maxDepth(root) endl; cout Node Count: ; cout countNodes(root) endl; cout Search 15: ; cout search(root, 15) endl; deleteTree(root); return 0; }十七、二叉树中的经典思想这份代码实际上已经涵盖了思想体现BFSbuildTreeDFSmaxDepth后序遍历deleteTree递归maxDepth/deleteTree队列buildTree/printTree指针TreeNode这也是 LeetCode 二叉树题目的核心基础。十八、总结本文系统讲解了TreeNode 节点设计buildTree 层序建树deleteTree 内存释放printTree 层序打印maxDepth 最大深度理解这些内容后你已经具备独立完成绝大多数二叉树基础题目的能力。二叉树真正困难的部分并不是“写代码”而是理解递归理解树结构理解 DFS 与 BFS当你真正理解树 递归结构很多复杂题目都会变得清晰。