tree traversal (树的遍历) - inorder traversal (中序遍历)

tree traversal (树的遍历) - inorder traversal (中序遍历)

1. tree traversal - 树的遍历

二叉树的遍历 (traversing binary tree) 是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。遍历是将二叉树中的结点信息由非线性排列变为某种意义上的线性排列,遍历操作使非线性结构线性化。

前序遍历 (preorder) - 中序遍历 (inorder) - 后序遍历 (postorder) - 层序遍历 (breadth-first)。

二叉树由根结点、左子树和右子树三部分组成。假设 D、L、R 分别代表遍历根结点、遍历左子树、遍历右子树,则二叉树的遍历方式有 6 种:DLR、DRL、LDR、LRD、RDL、RLD。先遍历左子树和先遍历右子树在算法设计上没有本质区别,如果我们限制了从左到右的习惯方式,那么主要就分为前序遍历 (preorder) - 中序遍历 (inorder) - 后序遍历 (postorder) - 层序遍历 (breadth-first) 四种。

1. 深度优先搜索 (depth-first search,DFS)

二叉树的深度优先遍历可细分为前序遍历、中序遍历、后序遍历。这三种遍历可以用递归实现,也可使用迭代实现。

  1. DLR - 前序遍历 (根在前,从左往右,一棵树的根永远在左子树前面,左子树永远在右子树前面)。
  2. LDR - 中序遍历 (根在中,从左往右,一棵树的左子树永远在根前面,根永远在右子树前面)。
  3. LRD - 后序遍历 (根在后,从左往右,一棵树的左子树永远在右子树前面,右子树永远在根前面)。

前序遍历 (preorder) - 中序遍历 (inorder) - 后序遍历 (postorder) 是针对根节点而言的,左右子树的遍历顺序不变,前序就是根节点最先遍历,然后左右子树。中序是把根节点放在中间遍历。后序是把根节点放在最后遍历。

在这里插入图片描述

  1. 根是相对的,对于整棵树而言只有一个根,但对于每棵子树而言,又有自己的根。对于整棵树而言,A 是根,A 分别在前面、中间、后面被遍历到。对于 D,它是 G 和 H 的根。对于 D、G、H 这棵树而言,三种排序顺序分别是 DGH、GDH、GHD。对于 C,它是 E 和 F 的根,三种排序顺序分别是 CEF、ECF、EFC。
  2. 整棵树的起点,从 A 开始,前序遍历的话,一棵树的根永远在左子树前面,左子树又永远在右子树前面。
  3. 二叉树结点的先根序列、中根序列和后根序列中,所有叶子结点的先后顺序一样。

2. 广度优先搜索 - 宽度优先搜索 - 横向优先搜索 (breadth-first search,BFS)

层序遍历 (breadth-first) 是按层从上到下,从左到右遍历。

在这里插入图片描述

2. 中序遍历 (inorder)

二叉树有三类节点:父节点,左孩子节点,右孩子节点。前序遍历是先遍历父节点,之后左孩子节点,右孩子节点。中序和后序遍历都是针对父节点的,父节点中间遍历,父节点最后遍历。左右孩子节点的遍历顺序不变。

在这里插入图片描述

中序遍历是父节点在中间遍历,遍历的顺序是左孩子节点,父节点,右孩子节点。对于整棵树来说,0 是父节点,左边的树枝是左孩子节点,右边的树枝是右孩子节点。

在这里插入图片描述

  1. 对于 0 节点的整个左孩子树来说,这又是一个父子结构,3 是左孩子节点,1 是父节点,4 是右孩子节点。他们的遍历顺序是 3,1,4。
  2. 遍历父节点 0。
  3. 对于 0 节点的整个右孩子树来说,先遍历 2 的左孩子节点结构 7,5,遍历 2,最后遍历6。

中序遍历结果:3,1,4,0,7,5,2,6

3. 迭代实现中序遍历 (inorder)

(1) 右孩子节点的持续左孩子入栈,直到左孩子为空。
(2) 弹出栈元素输出,检查是否有右孩子节点,如果有进行 (1),如果没有继续弹出栈元素输出。

  1. 节点 0 入栈。
    在这里插入图片描述

  2. 节点 1、节点 3 入栈。
    在这里插入图片描述

  3. 节点 3 没有左孩子节点,节点 3 弹出栈输出。
    在这里插入图片描述

  4. 检查节点 3 没有右孩子节点,节点 1 出栈,输出。
    在这里插入图片描述

  5. 节点 1 有右孩子节点,入栈 1 的右孩子节点 4,以及节点 4 的所有持续左孩子节点。
    在这里插入图片描述

  6. 弹出栈顶元素,输出节点 4,检查节点 4 无右孩子。
    在这里插入图片描述

  7. 继续弹出栈顶元素 0,输出。
    在这里插入图片描述

  8. 将节点 0 的右孩子节点 2,及节点 2 遍历所有的左孩子节点入栈。
    在这里插入图片描述

  9. 因无左孩子可以再遍历入栈,弹出栈顶元素输出。
    在这里插入图片描述

  10. 弹出节点 7 输出,节点 7 无右孩子节点,继续弹栈。
    在这里插入图片描述

  11. 弹出栈顶元素 5,节点 5 无右孩子节点,继续弹栈。
    在这里插入图片描述

  12. 弹出栈顶元素 2,输出节点 2。节点 2 有右孩子节点,将节点 2 的右孩子节点 6,及节点 6 的持续左孩子节点,入栈。
    在这里插入图片描述

  13. 弹出栈顶元素 6,输出,栈为空。输出 3,1,4,0,7,5,2,6 结束循环。

References

https://dsa.cs.tsinghua.edu.cn/~deng/ds/dsacpp/
https://www.programiz.com/dsa/tree-traversal
http://btechsmartclass.com/data_structures/binary-tree-traversals.html
https://me.csdn.net/fanfan199312

发布了525 篇原创文章 · 获赞 1873 · 访问量 116万+

猜你喜欢

转载自blog.csdn.net/chengyq116/article/details/105070601