二叉树的三种基本遍历方式是前序遍历(Pre-order Traversal)、中序遍历(In-order Traversal)和后序遍历(Post-order Traversal)。这三种遍历方式各有特点,适用于不同的场景。下面是每种遍历方式的详细说明:
1. 前序遍历(Pre-order Traversal)
前序遍历的顺序是:根节点 -> 左子树 -> 右子树。
-
步骤:
- 访问根节点。
- 前序遍历左子树。
- 前序遍历右子树。
-
应用场景:
- 可以用来复制二叉树。
- 可以用来计算二叉树的节点数。
2. 中序遍历(In-order Traversal)
中序遍历的顺序是:左子树 -> 根节点 -> 右子树。
-
步骤:
- 中序遍历左子树。
- 访问根节点。
- 中序遍历右子树。
-
应用场景:
- 用于二叉搜索树,可以按照升序遍历所有节点。
- 可以用来计算二叉树的镜像。
3. 后序遍历(Post-order Traversal)
后序遍历的顺序是:左子树 -> 右子树 -> 根节点。
-
步骤:
- 后序遍历左子树。
- 后序遍历右子树。
- 访问根节点。
-
应用场景:
- 用于删除二叉树。
- 计算二叉树的深度。
示例图
实现方式
这三种遍历方式可以通过递归或迭代的方式实现。递归实现较为直观,而迭代实现通常需要使用栈来模拟递归过程。
递归实现
// 定义二叉树节点结构
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
// 前序遍历
void preOrder(TreeNode* root) {
if (root == NULL) return;
cout << root->val << " "; // 访问根节点
preOrder(root->left); // 遍历左子树
preOrder(root->right); // 遍历右子树
}
// 中序遍历
void inOrder(TreeNode* root) {
if (root == NULL) return;
inOrder(root->left); // 遍历左子树
cout << root->val << " "; // 访问根节点
inOrder(root->right); // 遍历右子树
}
// 后序遍历
void postOrder(TreeNode* root) {
if (root == NULL) return;
postOrder(root->left); // 遍历左子树
postOrder(root->right); // 遍历右子树
cout << root->val << " "; // 访问根节点
}
迭代实现
迭代实现通常使用栈来模拟递归过程,这里以非递归的前序遍历为例:
void preOrderIterative(TreeNode* root) {
if (root == NULL) return;
stack<TreeNode*> s;
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);
}
}
中序和后序遍历的迭代实现也可以类似地使用栈来完成。这些遍历方式是理解和操作二叉树的基础,掌握它们对于算法和数据结构的学习非常重要。