![8ed6367047c89d04e6ed2b5d183d1b3f.png](https://i-blog.csdnimg.cn/blog_migrate/b14f8f1ff63ad27ae6c71378ffcfc150.jpeg)
假设有这么一个二叉树如下:
![ac0ea4bd53dc1bdcf1a3263d48cfb016.png](https://i-blog.csdnimg.cn/blog_migrate/3a626f04808936f73d213741e5c6fa24.png)
根据上述的二叉树,可以计算到:
- 前序遍历结果:1, 2, 4, 5, 8, 9, 11, 3, 6, 7, 10
- 中序遍历结果:4, 2, 8, 5, 11, 9, 1, 6, 3, 10, 7
- 后序遍历结果:4, 8, 11, 9, 5, 2, 6, 10, 7, 3, 1
二叉树的类实现
class
深度优先遍历
递归实现
# 前序遍历(递归)
非递归实现
前序遍历
根据已有的认识,此函数需要一个栈,保存树尚未访问过的部分信息。对于前序遍历也会有不同的实现方法,下面考虑一种方法,即:
- 由于采取先序遍历,遇到结点就应该访问,下一步就应该沿着树的坐分支下行
- 但结点的右分支(右子树)还没有访问,因此需要记录,将右子结点入栈。
- 遇到空树时回溯,取出栈中保存的一个右分支,像一颗二叉树一样遍历它。
## 方法一 常规打印
非递归算法的一个价值是把算法过程完整的暴露出来,便于进行细致的分析。
时间复杂度:在非递归的算法中,因为在执行的过程中访问每个结点一次,一部分子树(所有右子树,方法一、二)被压入和弹出各一次(栈操作是O(1)时间),所以整个遍历过程需要的时间复杂度为O(n)。
空间复杂度:这里的关键因素是遍历中栈可能达到的最大深度(栈中元素的最大深度个数),而栈的最大深度由被遍历的二叉树的高度决定。由于二叉树的高度可能达到O(n),所以在最坏情况下,算法的空间复杂度为O(n),n个结点的二叉树的平均高度为O(log n),所以非递归前序遍历的平均空间复杂度为O(log n)。
在一些情况下,修改实现方法也可能降低空间的开销。对于上面函数,修改其定义,只把非空的右子树进栈,在很多情况下能减小一些空间开销。
其他非递归的遍历算法,包括中序遍历和后续遍历算法以及层次遍历算法,都可以直接了当的修改成迭代器。但是递归算法不可以。
中序遍历
# 中序遍历(左根右):模拟压栈过程
后序遍历
# 后序遍历(左右根):模拟逆序(根右左)存入数组b,然后再数组b逆序输出
广度优先遍历
## 方法1
![fe8aab829ca4acd59da4190564d7b03b.png](https://i-blog.csdnimg.cn/blog_migrate/d4fe78f0ae7479257ecab2d9549729c9.jpeg)