1.先序遍历
遍历过程如下:
- 访问根节点(可以是print或其他的操作)
- 先序遍历其左子树
- 先序遍历其右子树
很显然这里可以利用递归程序进行实现,大致的代码如下
def pre_order_traversal(root): if root: print(root.val) pre_order_traversal(root.left) pre_order_traversal(root.right)
图 先序遍历示意图
2.中序遍历
遍历过程:
- 中序遍历其左子树
- 访问根结点
- 中序遍历其右子树
def in_order_traversal(root): if root: in_order_traversal(root.left) print(root.val) in_order_traversal(root.right)
图 中序遍历示意图
输入上图这个二叉树后,对于A这个根结点,我们会先中序遍历其左子树(B为根结点的子树)之后才会访问A,所以按递归的思路我们走到了B,然后对于B这个根结点来说,我们会先中序遍历它的左子树D,所以我们走到D,对于根结点为D的子树,我们先中序遍历它的左子树,没有就不用管了,然后访问D,之后访问D的右子树,也没有,然后对于根结点为B的子树而言它的左子树就中序遍历完了,现在访问根结点B,然后访问B的以F为根结点右子树,对于F为根结点的子树,还是先中序遍历它的左子树。。。。就这样迭代就可以得到上图的便利顺序。
3.后序遍历
遍历顺序如下:
- 后续遍历其左子树
- 后序遍历其右子树
- 访问根结点
def post_order_traversal(root): if root: post_order_traversal(root.left) post_order_traversal(root.right) print(root.val)
图 后序遍历示意图
4.总结
不管是先序遍历、中序遍历还是后序遍历,它们走的结点路径是一样的,只是访问各个结点的时机不同。
图 访问各结点的时刻示意图
可以看到,对于每个结点都有三次访问它的机会。对于先序遍历来说,就是第一次碰到结点就对它进行访问了,而中序遍历就是在第二次碰到结点的时候进行访问,而后序遍历则是第三次碰到结点才进行访问。
需要注意的是,递归的操作是借助于堆栈进行实现的,也就是说我们可以不通过递归而是通过循环进行树的遍历。