二叉树是一种非常重要的数据结构,由二叉树演变而来的树堆、红黑树、平衡树、SPlay伸展树等数据结构都在其各自适应领域有着广泛的应用。通过总结这一段时间对二叉树知识的学习,接下来将通过一系列二叉树专题的文章来进行归纳总结。
首先让我们来了解一下二叉树的遍历,二叉树有着先序、中序和后序三种遍历顺序,其中中序遍历更是可以直接将二叉树中元素以有序序列输出。因为二叉树本身就是一个递归的结构实现,所以我们可以使用递归很轻松地实现二叉树的三种遍历,同时也可以利用数据栈实现非递归的二叉树三种遍历。
建立二叉树
二叉树结构
1 | typedef struct node |
这里定义了一个node
结构表示二叉树中的一个结点,Node
表示指向一个node
结点的指针。
生成二叉树
1 | Node insert(Node n, int data) |
二叉树递归遍历
先序遍历
1 | void PreOrder(Node n) |
中序遍历
1 | void MidOrder(Node n) |
后序遍历
1 | void PosrOrder(Node n) |
由上述代码可以清楚看到,使用递归的方式进行二叉树的遍历是非常方便的,我们需要做的就是改变打印操作的位置。
二叉树非递归遍历
先序遍历
1 | void PreOrder2() |
- 从根节点开始访问打印结点数据,并将结点入栈;
- 继续访问结点的左儿子结点,继续执行第一步打印入栈操作;
- 如果左儿子结点为空,则进行出栈操作,将出栈结点右儿子结点入栈;
- 直到当前结点为空并且栈为空的时候,结束遍历。
中序遍历
1 | void MidOrder2() |
- 设置初始结点为根节点,依次访问其左儿子结点并依次入栈;
- 若左儿子结点为空,则进行出栈操作,访问打印该结点数据;
- 访问当前结点的右儿子结点,并进行第一步操作,继续访问其左儿子结点;
- 直到当前结点为空并且栈为空,结束遍历。
后序遍历
1 | void PosrOrder2() |
- 设置
cur
和pre
两个结点指针,分别指向当前结点和前一个结点;- 如果当前结点
curr
没有左右儿子结点,则直接执行打印操作;- 或者前一结点
pre
是当前结点的左儿子或右儿子,也直接执行打印操作;- 否则,依次将当前结点的右儿子、左儿子依次入栈,先右后左保证先左后右的遍历顺序;
- 如果栈为空则结束遍历操作;
完整代码
1 |
|