二叉树的遍历主要分为深度优先遍历(dfs)和广度优先遍历(bfs)。
深度优先遍历包括前序遍历、中序遍历和后序遍历,这三种遍历方式都有递归和迭代两种实现方式。
广度优先遍历也就是通常我们所说的层次遍历,通常用迭代方式实现。
前序、中序与后序都是从根节点的视角描述的,前序遍历顺序是根节点——左子树——右子树
,中序是左子树——根节点——右子树
,后序是左子树——右子树——根节点
。
树的定义本身就是递归定义,所以采用递归方式实现树的前序、中序、后序遍历容易理解且代码简洁。方法的调用栈会保证树的完全遍历。
而通过非递归的方式实现遍历,则需要借助其他的数据结构,比如栈、队列、堆等。
递归和迭代本质上都是循环。
递归存在着方法调用方法自身。迭代暗示着循环的某次计算结果(输出)会作为下一次循环计算的参数(输入)。
1. 深度优先遍历
节点定义。
class TreeNode{ |
1.1 前序遍历
递归方式实现。
public void preOrderTraversal(TreeNode root){ |
迭代方式实现。
//利用 栈 模拟 递归过程 实现循环前序遍历二叉树 |
1.2 中序遍历
递归方式实现。
public void inOrderTraversal(TreeNode root){ |
迭代方式实现。
|
1.3 后序遍历
递归方式实现。
public void postOrderTraversal(TreeNode root){ |
迭代方式实现。
//后序遍历与前、中序遍历不太一样 |
2. 广度优先遍历(层次遍历)
通过迭代方式实现。
public void levelTraversal(TreeNode root){ |
这里可以对照着广度优先遍历的代码形式,重新描述一下深度优先遍历(非递归实现前序遍历)。
下述这种遍历方式不具备扩展性,类似于图的深度优先遍历(DFS)。这种方式应该是对先序遍历的一种特殊实现,思路清晰明了,在中序和后序方式中不适用。
public void depthOrderTraversal(TreeNode root){ |