二叉树(Binary Tree)是数据结构中最重要的非线性结构之一。掌握二叉树的遍历方法是算法学习的基础,本文将全面讲解四种经典遍历方式:
层次遍历(Level Order)
先序遍历(PreOrder)
中序遍历(InOrder)
后序遍历(PostOrder)
通过清晰的代码实现和示意图,帮助读者彻底理解它们的区别与应用场景。
typedef struct BiTNode {
int data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
特点:按层级从上到下、从左到右访问节点
应用:求树的高度、打印树结构
实现:需借助队列
void LevelOrder(BiTree T) {
if (T == NULL) return;
LinkQueue Q;
InitQueue(Q);
EnQueue(Q, T);
BiTree p;
while (!IsEmpty(Q)) {
DeQueue(Q, p);
visit(p);
if (p->lchild) EnQueue(Q, p->lchild);
if (p->rchild) EnQueue(Q, p->rchild);
}
}
示例:
1
/ \
2 3
输出:1 2 3
特点:根 → 左子树 → 右子树
应用:复制二叉树、前缀表达式
递归实现:
void PreOrder(BiTree T) {
if (T != NULL) {
visit(T); // 访问根
PreOrder(T->lchild); // 左子树
PreOrder(T->rchild); // 右子树
}
}
非递归实现(需栈):
void PreOrder_NonRecursive(BiTree T) {
stack s;
BiTree p = T;
while (p || !s.empty()) {
if (p) {
visit(p);
s.push(p);
p = p->lchild;
} else {
p = s.top();
s.pop();
p = p->rchild;
}
}
}
示例:
输出:1 2 3
特点:左子树 → 根 → 右子树
应用:二叉搜索树排序
递归实现:
void InOrder(BiTree T) {
if (T != NULL) {
InOrder(T->lchild); // 左子树
visit(T); // 访问根
InOrder(T->rchild); // 右子树
}
}
非递归实现:
void InOrder_NonRecursive(BiTree T) {
stack s;
BiTree p = T;
while (p || !s.empty()) {
if (p) {
s.push(p);
p = p->lchild;
} else {
p = s.top();
visit(p);
s.pop();
p = p->rchild;
}
}
}
示例:
输出:2 1 3
特点:左子树 → 右子树 → 根
应用:释放二叉树内存、后缀表达式
递归实现:
void PostOrder(BiTree T) {
if (T != NULL) {
PostOrder(T->lchild); // 左子树
PostOrder(T->rchild); // 右子树
visit(T); // 访问根
}
}
非递归实现(需双栈):
void PostOrder_NonRecursive(BiTree T) {
stack s1, s2;
s1.push(T);
while (!s1.empty()) {
BiTree p = s1.top();
s1.pop();
s2.push(p);
if (p->lchild) s1.push(p->lchild);
if (p->rchild) s1.push(p->rchild);
}
while (!s2.empty()) {
visit(s2.top());
s2.pop();
}
}
示例:
输出:2 3 1
遍历方式 | 访问顺序 | 应用场景 | 实现难度 |
---|---|---|---|
层次遍历 | 按层级 | 打印树结构、BFS | 中等 |
先序遍历 | 根 → 左 → 右 | 复制树、前缀表达式 | 简单 |
中序遍历 | 左 → 根 → 右 | 二叉搜索树排序 | 简单 |
后序遍历 | 左 → 右 → 根 | 释放内存、后缀表达式 | 较难 |
#include
#include
#include
using namespace std;
// 二叉树节点定义
typedef struct BiTNode {
int data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
// 初始化二叉树
BiTree CreateTree() {
BiTree root = new BiTNode{1, NULL, NULL};
root->lchild = new BiTNode{2, NULL, NULL};
root->rchild = new BiTNode{3, NULL, NULL};
return root;
}
// 访问节点
void visit(BiTree p) {
cout << p->data << " ";
}
// 先序遍历(递归)
void PreOrder(BiTree T) {
if (T) {
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
// 中序遍历(递归)
void InOrder(BiTree T) {
if (T) {
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}
// 后序遍历(递归)
void PostOrder(BiTree T) {
if (T) {
PostOrder(T->lchild);
PostOrder(T->rchild);
visit(T);
}
}
// 层次遍历(队列)
void LevelOrder(BiTree T) {
if (!T) return;
queue q;
q.push(T);
while (!q.empty()) {
BiTree p = q.front();
q.pop();
visit(p);
if (p->lchild) q.push(p->lchild);
if (p->rchild) q.push(p->rchild);
}
}
int main() {
BiTree root = CreateTree();
cout << "先序遍历: ";
PreOrder(root); // 1 2 3
cout << "\n中序遍历: ";
InOrder(root); // 2 1 3
cout << "\n后序遍历: ";
PostOrder(root); // 2 3 1
cout << "\n层次遍历: ";
LevelOrder(root); // 1 2 3
return 0;
}
答:递归本质是栈操作,非递归需用显式栈模拟递归过程。
若需层级操作 → 层次遍历
若需父节点优先 → 先序遍历
若需排序结果(BST)→ 中序遍历
若需子节点优先 → 后序遍历
层次遍历:队列实现,BFS经典应用。
先/中/后序遍历:递归或栈实现,区别仅在于访问根的时机。
非递归实现:建议掌握,面试高频考点。