04-二叉树
💡 核心结论
二叉树本质
定义:每个节点最多有两个子节点的树结构
遍历:前序、中序、后序、层序,各有应用场景
深度优先:递归(前中后序)或栈实现
广度优先:队列实现层序遍历
应用:表达式树、文件系统、DOM树
遍历方式对比
遍历 |
顺序 |
应用 |
实现 |
|---|---|---|---|
前序 |
根→左→右 |
复制树、序列化 |
递归/栈 |
中序 |
左→根→右 |
BST有序输出 |
递归/栈 |
后序 |
左→右→根 |
删除树、计算表达式 |
递归/栈 |
层序 |
逐层 |
打印层级、BFS |
队列 |
关键概念
满二叉树:每层都满,节点数 = 2^h - 1
完全二叉树:除最后一层外都满,最后一层从左到右连续
平衡二叉树:左右子树高度差 ≤ 1
深度:从根到节点的边数
高度:从节点到叶子的最长路径
性质
n个节点的二叉树高度:⌈log₂(n+1)⌉ ≤ h ≤ n
第i层最多有 2^(i-1) 个节点
深度为h的二叉树最多有 2^h - 1 个节点
🌳 二叉树遍历
递归遍历
def preorder(root): # 前序:根左右
if not root: return
print(root.val)
preorder(root.left)
preorder(root.right)
def inorder(root): # 中序:左根右
if not root: return
inorder(root.left)
print(root.val)
inorder(root.right)
def postorder(root): # 后序:左右根
if not root: return
postorder(root.left)
postorder(root.right)
print(root.val)
迭代遍历(重要)
# 前序(栈)
def preorder_iterative(root):
if not root: return []
stack, result = [root], []
while stack:
node = stack.pop()
result.append(node.val)
if node.right: stack.append(node.right)
if node.left: stack.append(node.left)
return result
# 中序(栈)
def inorder_iterative(root):
stack, result = [], []
curr = root
while curr or stack:
while curr:
stack.append(curr)
curr = curr.left
curr = stack.pop()
result.append(curr.val)
curr = curr.right
return result
# 层序(队列)
def levelorder(root):
if not root: return []
queue, result = [root], []
while queue:
node = queue.pop(0)
result.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
return result
🎯 常见问题
树的高度/深度
def height(root):
if not root: return 0
return 1 + max(height(root.left), height(root.right))
节点数
def count_nodes(root):
if not root: return 0
return 1 + count_nodes(root.left) + count_nodes(root.right)
镜像翻转
def mirror(root):
if not root: return
root.left, root.right = root.right, root.left
mirror(root.left)
mirror(root.right)
路径和
def has_path_sum(root, target):
if not root: return False
if not root.left and not root.right:
return root.val == target
return (has_path_sum(root.left, target - root.val) or
has_path_sum(root.right, target - root.val))
📚 LeetCode练习
💻 完整代码实现
Python 实现
1"""
2二叉树实现和遍历
3"""
4
5class TreeNode:
6 """二叉树节点"""
7
8 def __init__(self, val=0, left=None, right=None):
9 self.val = val
10 self.left = left
11 self.right = right
12
13
14class BinaryTree:
15 """二叉树"""
16
17 def __init__(self):
18 self.root = None
19
20 # ========== 递归遍历 ==========
21
22 def preorder(self, root):
23 """前序遍历:根→左→右"""
24 if not root:
25 return []
26 return [root.val] + self.preorder(root.left) + self.preorder(root.right)
27
28 def inorder(self, root):
29 """中序遍历:左→根→右"""
30 if not root:
31 return []
32 return self.inorder(root.left) + [root.val] + self.inorder(root.right)
33
34 def postorder(self, root):
35 """后序遍历:左→右→根"""
36 if not root:
37 return []
38 return self.postorder(root.left) + self.postorder(root.right) + [root.val]
39
40 # ========== 迭代遍历 ==========
41
42 def preorder_iterative(self, root):
43 """前序遍历(迭代)"""
44 if not root:
45 return []
46
47 stack, result = [root], []
48 while stack:
49 node = stack.pop()
50 result.append(node.val)
51 # 先压右子树,再压左子树(栈是后进先出)
52 if node.right:
53 stack.append(node.right)
54 if node.left:
55 stack.append(node.left)
56 return result
57
58 def inorder_iterative(self, root):
59 """中序遍历(迭代)"""
60 stack, result = [], []
61 curr = root
62
63 while curr or stack:
64 # 一直往左走
65 while curr:
66 stack.append(curr)
67 curr = curr.left
68 # 处理节点
69 curr = stack.pop()
70 result.append(curr.val)
71 # 转向右子树
72 curr = curr.right
73
74 return result
75
76 def levelorder(self, root):
77 """层序遍历(BFS)"""
78 if not root:
79 return []
80
81 queue, result = [root], []
82 while queue:
83 node = queue.pop(0)
84 result.append(node.val)
85 if node.left:
86 queue.append(node.left)
87 if node.right:
88 queue.append(node.right)
89 return result
90
91 def levelorder_levels(self, root):
92 """层序遍历(分层)"""
93 if not root:
94 return []
95
96 queue, result = [root], []
97 while queue:
98 level_size = len(queue)
99 level_vals = []
100
101 for _ in range(level_size):
102 node = queue.pop(0)
103 level_vals.append(node.val)
104 if node.left:
105 queue.append(node.left)
106 if node.right:
107 queue.append(node.right)
108
109 result.append(level_vals)
110 return result
111
112 # ========== 树的性质 ==========
113
114 def height(self, root):
115 """树的高度"""
116 if not root:
117 return 0
118 return 1 + max(self.height(root.left), self.height(root.right))
119
120 def count_nodes(self, root):
121 """节点数"""
122 if not root:
123 return 0
124 return 1 + self.count_nodes(root.left) + self.count_nodes(root.right)
125
126 def is_balanced(self, root):
127 """判断是否平衡"""
128 def check(node):
129 if not node:
130 return 0, True
131
132 left_height, left_balanced = check(node.left)
133 right_height, right_balanced = check(node.right)
134
135 balanced = (left_balanced and right_balanced and
136 abs(left_height - right_height) <= 1)
137 height = 1 + max(left_height, right_height)
138
139 return height, balanced
140
141 return check(root)[1]
142
143 def mirror(self, root):
144 """镜像翻转"""
145 if not root:
146 return
147 root.left, root.right = root.right, root.left
148 self.mirror(root.left)
149 self.mirror(root.right)
150
151 def max_path_sum(self, root):
152 """最大路径和"""
153 self.max_sum = float('-inf')
154
155 def helper(node):
156 if not node:
157 return 0
158
159 left = max(0, helper(node.left))
160 right = max(0, helper(node.right))
161
162 # 更新最大路径和
163 self.max_sum = max(self.max_sum, node.val + left + right)
164
165 # 返回经过当前节点的最大单边路径
166 return node.val + max(left, right)
167
168 helper(root)
169 return self.max_sum
170
171
172def demo():
173 """演示二叉树操作"""
174 print("=== 二叉树演示 ===\n")
175
176 # 构建树
177 # 1
178 # / \
179 # 2 3
180 # / \
181 # 4 5
182
183 root = TreeNode(1)
184 root.left = TreeNode(2)
185 root.right = TreeNode(3)
186 root.left.left = TreeNode(4)
187 root.left.right = TreeNode(5)
188
189 tree = BinaryTree()
190 tree.root = root
191
192 # 遍历
193 print("前序遍历(递归):", tree.preorder(root))
194 print("前序遍历(迭代):", tree.preorder_iterative(root))
195 print()
196
197 print("中序遍历(递归):", tree.inorder(root))
198 print("中序遍历(迭代):", tree.inorder_iterative(root))
199 print()
200
201 print("后序遍历(递归):", tree.postorder(root))
202 print()
203
204 print("层序遍历:", tree.levelorder(root))
205 print("层序遍历(分层):", tree.levelorder_levels(root))
206 print()
207
208 # 性质
209 print(f"树的高度: {tree.height(root)}")
210 print(f"节点数: {tree.count_nodes(root)}")
211 print(f"是否平衡: {tree.is_balanced(root)}")
212
213
214if __name__ == '__main__':
215 demo()
216
C++ 实现
1/**
2 * 二叉树实现和遍历
3 */
4
5#include <iostream>
6#include <vector>
7#include <stack>
8#include <queue>
9
10struct TreeNode {
11 int val;
12 TreeNode* left;
13 TreeNode* right;
14
15 TreeNode(int v) : val(v), left(nullptr), right(nullptr) {}
16};
17
18
19class BinaryTree {
20public:
21 TreeNode* root;
22
23 BinaryTree() : root(nullptr) {}
24
25 // ========== 递归遍历 ==========
26
27 void preorder(TreeNode* node, std::vector<int>& result) {
28 if (!node) return;
29 result.push_back(node->val);
30 preorder(node->left, result);
31 preorder(node->right, result);
32 }
33
34 void inorder(TreeNode* node, std::vector<int>& result) {
35 if (!node) return;
36 inorder(node->left, result);
37 result.push_back(node->val);
38 inorder(node->right, result);
39 }
40
41 void postorder(TreeNode* node, std::vector<int>& result) {
42 if (!node) return;
43 postorder(node->left, result);
44 postorder(node->right, result);
45 result.push_back(node->val);
46 }
47
48 // ========== 迭代遍历 ==========
49
50 std::vector<int> preorderIterative(TreeNode* root) {
51 std::vector<int> result;
52 if (!root) return result;
53
54 std::stack<TreeNode*> st;
55 st.push(root);
56
57 while (!st.empty()) {
58 TreeNode* node = st.top();
59 st.pop();
60 result.push_back(node->val);
61
62 if (node->right) st.push(node->right);
63 if (node->left) st.push(node->left);
64 }
65
66 return result;
67 }
68
69 std::vector<int> inorderIterative(TreeNode* root) {
70 std::vector<int> result;
71 std::stack<TreeNode*> st;
72 TreeNode* curr = root;
73
74 while (curr || !st.empty()) {
75 while (curr) {
76 st.push(curr);
77 curr = curr->left;
78 }
79 curr = st.top();
80 st.pop();
81 result.push_back(curr->val);
82 curr = curr->right;
83 }
84
85 return result;
86 }
87
88 std::vector<int> levelorder(TreeNode* root) {
89 std::vector<int> result;
90 if (!root) return result;
91
92 std::queue<TreeNode*> q;
93 q.push(root);
94
95 while (!q.empty()) {
96 TreeNode* node = q.front();
97 q.pop();
98 result.push_back(node->val);
99
100 if (node->left) q.push(node->left);
101 if (node->right) q.push(node->right);
102 }
103
104 return result;
105 }
106
107 // ========== 树的性质 ==========
108
109 int height(TreeNode* node) {
110 if (!node) return 0;
111 return 1 + std::max(height(node->left), height(node->right));
112 }
113
114 int countNodes(TreeNode* node) {
115 if (!node) return 0;
116 return 1 + countNodes(node->left) + countNodes(node->right);
117 }
118
119 void mirror(TreeNode* node) {
120 if (!node) return;
121 std::swap(node->left, node->right);
122 mirror(node->left);
123 mirror(node->right);
124 }
125
126 // ========== 打印 ==========
127
128 void printVector(const std::vector<int>& vec) {
129 std::cout << "[";
130 for (size_t i = 0; i < vec.size(); i++) {
131 std::cout << vec[i];
132 if (i < vec.size() - 1) std::cout << ", ";
133 }
134 std::cout << "]" << std::endl;
135 }
136
137 ~BinaryTree() {
138 deleteTree(root);
139 }
140
141 void deleteTree(TreeNode* node) {
142 if (node) {
143 deleteTree(node->left);
144 deleteTree(node->right);
145 delete node;
146 }
147 }
148};
149
150
151int main() {
152 std::cout << "=== 二叉树演示 ===" << std::endl << std::endl;
153
154 // 构建树
155 // 1
156 // / \
157 // 2 3
158 // / \
159 // 4 5
160
161 BinaryTree tree;
162 tree.root = new TreeNode(1);
163 tree.root->left = new TreeNode(2);
164 tree.root->right = new TreeNode(3);
165 tree.root->left->left = new TreeNode(4);
166 tree.root->left->right = new TreeNode(5);
167
168 // 遍历
169 std::vector<int> result;
170
171 tree.preorder(tree.root, result);
172 std::cout << "前序遍历(递归): ";
173 tree.printVector(result);
174
175 std::cout << "前序遍历(迭代): ";
176 tree.printVector(tree.preorderIterative(tree.root));
177 std::cout << std::endl;
178
179 result.clear();
180 tree.inorder(tree.root, result);
181 std::cout << "中序遍历(递归): ";
182 tree.printVector(result);
183
184 std::cout << "中序遍历(迭代): ";
185 tree.printVector(tree.inorderIterative(tree.root));
186 std::cout << std::endl;
187
188 result.clear();
189 tree.postorder(tree.root, result);
190 std::cout << "后序遍历(递归): ";
191 tree.printVector(result);
192 std::cout << std::endl;
193
194 std::cout << "层序遍历: ";
195 tree.printVector(tree.levelorder(tree.root));
196 std::cout << std::endl;
197
198 // 性质
199 std::cout << "树的高度: " << tree.height(tree.root) << std::endl;
200 std::cout << "节点数: " << tree.countNodes(tree.root) << std::endl;
201
202 return 0;
203}