C++ Binary Tree Traversal

关于二叉树的遍历有很多的方法, 下面介绍两个经典的遍历算法: BFS和DFS。一个是深度优先遍历, 一个是广度有优先遍历。 这两种遍历算法均属于盲目的遍历算法, 一般而言, 启发式的遍历搜索算法比较好一些。 。 关于各种遍历算法的对比, 将会在后面逐一提及。 这里不在赘述。

由于树是一个非线性的数据结构, 显然不能像linked list , 或者Array那样通过从头像最末尾移动去实现遍历每一个元素, 我们使用的是BFS和DFS算法。

例如下面的一个二叉树:

 

所谓的树遍历(Tree traversal)就是 process of visiting each node in the tree exactly once in some order。

这里, visiting的含义就是reading/processing  data in a node, 例如打印节点的数据(data)。

根据树的节点被遍历的order, 主要有两个经典的遍历算法: BFS(breadth first search)和DFS(depth first search)(这也是在图这个数据结构中常用的遍历图的算法)。

我们可以将Trees视为一种特殊的graph data structures。

 

BFS: 遍历树节点的顺序是逐层逐层的将所有的节点遍历完。 

 

DFS: 深度优先遍历,

不难看出, BFS主要有三种遍历形式, preorder, inorder, 还有post order的形式(尽管L和R看起来可以交换顺序, 这样就变成了6种, 但是in  convention, 我们认为一般从左子树开始, 所以姑且认为有3种, 而非6种)下面一一介绍:

Preorder traversal of the binary tree:

访问的顺序为:

遍历到A节点时候, 打印A的数据, 然后查看左子树。 此时A的左子树为NULL, 于是开始查看A的右子树:

 

 

 

 

后由于这个节点是叶节点A, A的右子树也是NULL, 于是返回到节点B(递归返回), 查看节点B的右子树, B有右子树, 所以开始遍历右子树:

 

对于节点D, 同样的:

接下来, 返回到节点D, 访问其右子树:

于是到达E点, 同样的打印出数据, 访问左子树, 为NULL, 再访问右子树, 同样为NULL, 递归返回到根节点处:

最终我们访问完了根节点F的所有left subtree 的节点, 开始去访问F的right subtree, 先到J点, 打印出J节点数据, 让后访问左子树, 到达G点, 发现没有左子树, 访问G的右子树。

于是访问G的子树, 到达I节点, 打印出I的数据, 访问I的左子树, 不是NULL, 到达H ,打印出H的data, 由于H是叶子节点, 所以左右子树均为NULL, 递归返回到I, 返现I的右子树也是NULL, 返回到J:

 

 看到J的右子树不是NULL, 访问K节点, 打印出数据K的左右子树均为NULL, 所以最终所有的节点均被访问了:

 

 

DFS中的: Inorder Traversal 如下:

接下来, 到达A, 发现A的左子树为NULL, 接下来打印出数据, 开始访问A的右子树, 亦为NULL, 所以返回到节点B处, 打印出B的数据, 然后访问节点B的右子树, 于是到达节点C, 访问节点C的左子树, 为NULL, 所以打印出节点C的数据, 然后访问节点C的左子树, 也是NULL, 于是就返回到D:

 

递归返回到节点D的时候, 打印出节点D的数据, 开始访问节点D的右子树, 到达E, 同样有:

 

等等, 省略中间步骤, 最终遍历完所有的节点:

 

NOTE: 之所以叫做inorder, 是因为如果是一个BST, 我们最终打印出来的顺序是一个排好序的(从小到达的)数据。

 

PostOrder traversal,  同理, 很容易理解。 具体的访问节点的顺序如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值