一、三种遍历的定义
二叉树遍历是一个递归过程:先处理根节点,再分别处理左、右子树。根据"根节点"被访问的位置不同,有三种深度优先遍历3:
-
前序遍历 :根 → 左子树 → 右子树
先访问根节点,再前序遍历左子树,最后前序遍历右子树。
-
中序遍历 :左子树 → 根 → 右子树
先中序遍历左子树,再访问根节点,最后中序遍历右子树。
-
后序遍历 :左子树 → 右子树 → 根
先后序遍历左子树,再后序遍历右子树,最后访问根节点。
递归和非递归实现得到的序列完全一致,非递归只是用显式栈模拟递归过程。
二、示例
例如二叉树:
text
1
/ \
2 3
/ \ \
4 5 6
-
前序序列:1,2,4,5,3,61,2,4,5,3,6
-
中序序列:4,2,5,1,3,64,2,5,1,3,6
-
后序序列:4,5,2,6,3,14,5,2,6,3,1
三、遍历序列的重要性质
1. 子树在序列中是连续区间
以任意节点为根的子树,在三种序列中都对应一个连续区间。并且在这个区间内:
-
前序序列中,根节点在区间最前面;
-
中序序列中,根节点在左子树区间和右子树区间之间;
-
后序序列中,根节点在区间最后面。
这是"由遍历序列还原二叉树"的核心基础。
2. 根节点的定位
-
前序序列的第一个元素一定是整棵树的根节点。
-
后序序列的最后一个元素一定是整棵树的根节点。
-
中序序列中,根节点左边的元素全部来自左子树,右边的元素全部来自右子树。
因此,只要有了"中序 + 前序"或"中序 + 后序",就能确定根,并区分左右子树。
3. 二叉树还原的唯一性
-
前序序列 + 中序序列:能唯一确定一棵二叉树。
-
后序序列 + 中序序列:能唯一确定一棵二叉树。
-
前序序列 + 后序序列:一般不能唯一确定二叉树。
反例:树 A 是根节点 1 只有左孩子 2;树 B 是根节点 1 只有右孩子 2。
树 A 和树 B 的前序序列都是 1,21,2,后序序列都是 2,12,1,但它们是两棵不同的二叉树。
所以,已知前序和中序可以唯一推出后序;已知后序和中序可以唯一推出前序;但只知道前序和后序,无法唯一确定中序遍历序列。
若额外限制为严格二叉树 (每个内部节点都有左右两个孩子),则前序 + 后序可以唯一还原二叉树1。
4. 与二叉搜索树的关系
对于二叉搜索树(BST):
-
中序遍历序列一定按关键字递增排列;
-
因为中序序列隐含已知,所以仅凭前序序列或后序序列也能唯一重建这棵 BST。
5. 表达式树中的应用
表达式树的前序、中序、后序遍历分别对应:
-
前序序列:前缀表达式;
-
中序序列:中缀表达式;
-
后序序列:后缀表达式,也就是逆波兰式,用栈求值非常方便。
6. 其他性质
-
三种深度优先遍历中,叶子节点的从左到右相对顺序相同。
-
三种遍历的时间复杂度都是 O(n)O(n),其中 nn 是节点数;递归栈空间为 O(h)O(h),hh 是树高,最坏情况下为 O(n)O(n)。
四、由序列还原二叉树的方法
前序 + 中序还原:
-
前序序列的第一个元素是根节点;
-
在中序序列中找到根节点,根左侧长度为 LL;
-
前序序列中,根节点之后的前 LL 个元素属于左子树,剩余元素属于右子树;
-
递归处理左右子树即可1 2。
后序 + 中序还原:
-
后序序列的最后一个元素是根节点;
-
在中序序列中找到根节点,根左侧长度为 LL;
-
后序序列中,前 LL 个元素属于左子树,接下来若干元素属于右子树,最后是根节点;
-
递归处理左右子树即可1 2。