一、概念说明
在二叉树(Binary Tree)中,遍历是指按照某种顺序访问树中每个节点一次且仅一次。
三种经典的深度优先遍历(DFS)方式是:
遍历方式 | 访问顺序 | 特点与应用场景 |
---|---|---|
前序遍历 | 根 → 左 → 右 | 常用于复制树、构建前缀表达式等 |
中序遍历 | 左 → 根 → 右 | 用于获取有序序列(如二叉搜索树) |
后序遍历 | 左 → 右 → 根 | 常用于释放内存、构建后缀表达式等 |
二、图示与举例
示例二叉树结构如下:
A
/ \
B C
/ \ \
D E F
✅ 1. 前序遍历(Pre-order)
-
顺序:根 → 左子树 → 右子树
-
示例输出:
A → B → D → E → C → F
✅ 2. 中序遍历(In-order)
-
顺序:左子树 → 根 → 右子树
-
示例输出:
D → B → E → A → C → F
✅ 3. 后序遍历(Post-order)
-
顺序:左子树 → 右子树 → 根
-
示例输出:
D → E → B → F → C → A
三、遍历的递归实现(C++)
假设有如下结构体:
struct TreeNode {
char val;
TreeNode* left;
TreeNode* right;
TreeNode(char x) : val(x), left(nullptr), right(nullptr) {}
};
🌟 前序遍历
void preorder(TreeNode* root) {
if (!root) return;
cout << root->val << " ";
preorder(root->left);
preorder(root->right);
}
🌟 中序遍历
void inorder(TreeNode* root) {
if (!root) return;
inorder(root->left);
cout << root->val << " ";
inorder(root->right);
}
🌟 后序遍历
void postorder(TreeNode* root) {
if (!root) return;
postorder(root->left);
postorder(root->right);
cout << root->val << " ";
}
四、非递归(迭代)实现核心思想
前序遍历(借助栈)
void preorderIterative(TreeNode* root) {
stack<TreeNode*> s;
if (root) s.push(root);
while (!s.empty()) {
TreeNode* node = s.top(); s.pop();
cout << node->val << " ";
if (node->right) s.push(node->right);
if (node->left) s.push(node->left);
}
}
中序遍历(借助栈)
void inorderIterative(TreeNode* root) {
stack<TreeNode*> s;
TreeNode* curr = root;
while (curr || !s.empty()) {
while (curr) {
s.push(curr);
curr = curr->left;
}
curr = s.top(); s.pop();
cout << curr->val << " ";
curr = curr->right;
}
}
后序遍历(双栈实现)
void postorderIterative(TreeNode* root) {
if (!root) return;
stack<TreeNode*> s1, s2;
s1.push(root);
while (!s1.empty()) {
TreeNode* node = s1.top(); s1.pop();
s2.push(node);
if (node->left) s1.push(node->left);
if (node->right) s1.push(node->right);
}
while (!s2.empty()) {
cout << s2.top()->val << " ";
s2.pop();
}
}
五、应用场景举例
遍历方式 | 应用场景 |
---|---|
前序遍历 | 构建树、序列化、拷贝、构建前缀表达式 |
中序遍历 | 获取有序结果(二叉搜索树)、表达式求值 |
后序遍历 | 释放内存、删除树、构建后缀表达式 |
六、记忆方法
一句话记忆:
- 前序:「我先说(根),然后左看看,再右看看」
- 中序:「我先左看看,再说话(根),再右看看」
- 后序:「我把两边(左、右)看完,最后才说话(根)」