用递归的话这两个题是很简单的。
在非递归的情况,使用迭代做这个两个题目,两个题目间的联系是很紧密的。
首先是LeetCode144,前序遍历二叉树:
前序遍历的顺序为:根,左,右。
对这个顺序下,很容易想到使用一个栈即可完成遍历,流程有:
1).根节点入栈
2).读取根节点出栈
3).右节点与左节点入栈.
迭代这个流程直到栈空。
其次是LeetCode145,后序遍历二叉树:
后序遍历的顺序为:左,右,根。
有一种思路是:
首先记录最近遍历的那个节点
然后考虑目前栈顶的这个节点,如果栈顶节点为:
1).叶子节点:说明是叶子,应该遍历了
2).最近遍历节点为栈顶的右子节点:说明它的左右子树已经便遍历完了,它应该作为根被遍历
否则,应该按右,左的顺序入栈。
如此遍历直到栈空。
另有一种思路,利用了与前序遍历的联系:
前序遍历的流程:
根节点,左子树,右子树
而后续遍历的流程为:
左子树,右子树,根
后续遍历可以看做将 :
根,右子树,左子树
的遍历顺序翻转的结果。
而对于先遍历根的遍历方法,我们已经有了前序遍历的思路了,只需要将左右子树入栈的顺序调换下即可:
前序遍历的思路是:
1).根节点入栈
2).读取根节点出栈
3).右节点与左节点入栈.
现在对于
根,右子树,左子树这个顺序只需要更改下3)即可:
1).根节点入栈
2).读取根节点,根节点出栈
3)左节点入栈,右节点入栈.
这个结果就是 根 右子树 左子树的遍历顺序
只需要将这个结果翻转,即可得到后序遍历的顺序。