Skip to content

中序遍历

中序遍历的特点

中序遍历按"左->根->右"的顺序访问,对于二叉排序树(BST),中序遍历的结果恰好是递增序列——这是 BST 最重要的性质之一。408 考试中,中序遍历是出现频率最高的遍历方式:判断 BST 合法性、求第 k 小元素、线索二叉树的线索化过程,底层都依赖中序遍历。

核心思想

中序遍历的访问顺序:左子树 → 根结点 → 右子树(LNR)。

以下面的二叉树为例:

        A
       / \
      B   C
     / \   \
    D   E   F

中序遍历序列为:D → B → E → A → C → F

递归过程展开:

  1. 先递归遍历 A 的左子树(以 B 为根)
  2. 再递归遍历 B 的左子树(以 D 为根)
  3. D 无左子树,访问 D;D 无右子树,返回
  4. 访问 B
  5. 递归遍历 B 的右子树,访问 E
  6. 左子树遍历完毕,访问 A(根结点)
  7. 递归遍历 A 的右子树(以 C 为根)
  8. C 无左子树,访问 C
  9. 递归遍历 C 的右子树,访问 F

中序遍历流程图

中序遍历的核心顺序:左 → 根 → 右。先递归处理左子树,再访问根结点,最后递归处理右子树。对 BST 进行中序遍历可得到递增有序序列。

交互可视化

通过下方的交互动画,你可以逐步观察中序遍历的执行过程:

加载可视化中...

操作详解

递归实现

递归实现思路非常直观,直接按照"左→根→右"的定义编写即可。

c
typedef struct BiTNode {
    int data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

void InOrder(BiTree T) {
    if (T == NULL) return;
    InOrder(T->lchild);   // 递归遍历左子树
    visit(T);             // 访问根结点
    InOrder(T->rchild);   // 递归遍历右子树
}

递归实现代码简洁,但每次调用都会在系统栈中压入一个栈帧。当树的深度很大时,可能导致栈溢出。

非递归实现(栈)

非递归实现的核心思路:用一个显式栈来模拟递归过程。

关键步骤:

  1. 从根结点出发,沿左子树一路入栈,直到左子树为空
  2. 栈顶元素出栈并访问
  3. 转向该结点的右子树,重复步骤 1
c
void InOrder_NonRecursive(BiTree T) {
    Stack S;
    InitStack(S);
    BiTree p = T;
    while (p != NULL || !IsEmpty(S)) {
        if (p != NULL) {
            Push(S, p);        // 当前结点入栈
            p = p->lchild;    // 一路向左
        } else {
            Pop(S, p);         // 左子树为空,弹出栈顶
            visit(p);          // 访问该结点
            p = p->rchild;    // 转向右子树
        }
    }
}

以上述示例树为例,栈的变化过程:

步骤操作栈内容(底→顶)访问结点
1A 入栈,向左A-
2B 入栈,向左A, B-
3D 入栈,向左A, B, D-
4左空,弹出 DA, BD
5D 右空,弹出 BAB
6转向 B 的右子树,E 入栈A, E-
7E 左空,弹出 EAE
8E 右空,弹出 A(空)A
9转向 A 的右子树,C 入栈C-
10C 左空,弹出 C(空)C
11转向 C 的右子树,F 入栈F-
12F 左空,弹出 F(空)F

最终访问顺序:D → B → E → A → C → F,与递归结果一致。

复杂度分析

实现方式时间复杂度空间复杂度说明
递归O(n)O(n)每个结点访问一次;栈深度最坏为 n(斜树)
非递归(栈)O(n)O(n)每个结点入栈、出栈各一次;栈空间最坏为 n

说明:n 为二叉树的结点总数。空间复杂度的最好情况为 O(log n),出现在完全二叉树等平衡结构中。

考研高频考点

  • ⭐ 对 BST 进行中序遍历可得到递增有序序列(选择题/判断题高频)
  • ⭐ 根据中序 + 先序(或后序)序列还原二叉树(大题必考)
  • ⭐ 中序遍历非递归算法的手写实现(算法题高频)
  • ⭐ 给定二叉树画出中序遍历序列(基础送分题)
  • 三种遍历的递归算法对比(仅 visit 位置不同)
  • 中序遍历在线索二叉树中的应用(中序线索化)

易错:中序遍历的非递归实现需要一个栈:从根开始不断将左孩子入栈,直到左孩子为空;然后弹出栈顶访问,再转向右子树重复过程。关键是不是先弹出再入栈左右孩子(那是先序的做法),而是先一路入栈到最左。

易错:对 BST 做中序遍历一定得到递增序列;反过来,如果一棵树的中序遍历不是递增序列,它一定不是 BST。408 判断题常用这个性质。

相关知识

真题练习

相关真题(7题)

2024Q3选择题2分

二叉树中序遍历:v 有两个孩子且中序序列为 ...p,v,q...,判断 p 和 q 的孩子情况

2022Q3选择题2分

二叉树中序遍历:中序序列中相邻结点 p、q 的可能关系(兄弟关系不可能)

2022Q41综合题8分

算法设计:顺序存储的二叉树判断是否为二叉搜索树(中序遍历递增性)

2018Q6选择题2分

BST 中序性质:中序遍历得到递增序列,判断结点大小关系

2017Q4选择题2分

二叉树遍历序列:先序=中序的充要条件是所有结点仅有右子树

2017Q41综合题15分

算法设计:表达式树转中缀表达式(中序遍历加括号)

树(综合)中序遍历
2009Q3选择题2分

二叉树遍历方式:根据遍历序列判断遍历方式为 RNL