- 先序/中序/后序遍历的非递归算法是用栈来实现的
- 入栈/出栈 ≠ \neq = 访问(输出的先序/中序/后序序列)
- 树本身是一样的,只是访问顺序不一样(先序/中序/后序序列都表示同一个树,同一个dfs)
- 先序遍历:根节点 -> 左子树 -> 右子树。访问后入栈!!! (好好体会!)
- 中序遍历:左子树 -> 根节点 -> 右子树。出栈后访问!!!(先入栈,到时机出栈后访问)
所以先序相当于入栈,中序相当于出栈(中序是多种出栈顺序的其中一种)
- 二叉树的中序序列作为入栈次序,前序序列作为对应出栈次序❌
尽管你可以在栈中首先存储左子树的所有节点,然后等到根节点到栈顶后再出栈,但是中序遍历是出站后访问,无法在出栈时同时遵循前序遍历的规则!根节点在前序遍历中必须在所有左子树之前被访问,而在中序遍历中,根节点必须在左子树之后被访问。这两个遍历顺序对根节点的处理时机是相冲突的,因此无法简单通过栈操作将中序遍历作为入栈顺序、前序遍历作为出栈顺序来实现。
二叉树示例验证
考虑以下二叉树:
1
/ \
2 3
/ \
4 5
先序遍历和入栈顺序
先序遍历顺序是:1 2 4 5 3 访问后入栈
- 访问根节点 1,入栈
[1]
- 访问左子节点 2,入栈
[1, 2]
- 访问左子节点 4,入栈
[1, 2, 4]
左子节点 4 无左孩子,处理下一个节点 - 访问右子节点 5,入栈
[1, 2, 4, 5]
右子节点 5 无孩子,处理下一个节点 - 访问右子节点 3,入栈
[1, 2, 4, 5, 3]
最后入栈顺序为 [1, 2, 4, 5, 3]
,即先序遍历顺序。
中序遍历和出栈顺序
中序遍历顺序是:4 2 5 1 3
按照先序遍历的入栈顺序 [1, 2, 4, 5, 3]
进行出栈和访问:
- 栈顶是 1,但中序遍历先访问左子树,所以继续处理左子树。
- 栈顶是 2,但中序遍历先访问左子树,所以继续处理左子树。
- 栈顶是 4,中序遍历先访问 4,出栈并访问,得到
[4]
,栈为[1, 2, 5, 3]
- 回到节点 2,中序遍历访问 2,出栈并访问,得到
[4, 2]
,栈为[1, 5, 3]
- 处理节点 5,中序遍历访问 5,出栈并访问,得到
[4, 2, 5]
,栈为[1, 3]
- 回到节点 1,中序遍历访问 1,出栈并访问,得到
[4, 2, 5, 1]
,栈为[3]
- 处理节点 3,中序遍历访问 3,出栈并访问,得到
[4, 2, 5, 1, 3]
最后出栈顺序为 [4, 2, 5, 1, 3]
,即中序遍历顺序。
题目
一棵二叉树的先序遍历序列为1234567,它的中序遍历序列可能是
A.3124567B. 1234567 C. 4135627 D. 1463572