目录
迭代实现二叉树的前中后序遍历
一 迭代实现前序遍历
前序遍历是中左右,如果当前节点还有左子树就一直向下找。直到当前节点没有左子树后再返回从最底层逐步向上向右找。则可写出如下代码:(注!代码中空节点不入栈)
public List<Integer> preorderTraversal(TreeNode root) {
// 存放遍历结果的列表
List<Integer> res = new ArrayList<>();
if(root == null) return res;
// 存放遍历到的节点,使得向左查找完毕后可以返回向右向上查找
Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode node = root;
while(!stack.isEmpty() || node != null){
while(node != null){
// 迭代一直查找左节点
res.add(node.val);
stack.push(node);
node = node.left;
}
// 若节点没有左孩子,则将节点出栈,并查找他是否有右孩子
node = stack.pop();
node = node.right;
}
return res;
}
二 迭代实现中序遍历
再来看中序遍历,中序遍历顺序为左中右,先访问二叉树左子树的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是把节点值存进res列表)。然后处理其父节点,再处理其父节点的右节点。处理完后再继续回到上一层的父节点,如此重复迭代而已。在使用迭代法写中序遍历时,就需要借用指针的遍历来帮助访问接待你,栈则用来处理节点上的元素。
具体实现代码如下:
public List<Integer> inorderTraversal(TreeNode root) {
// 存放遍历结果的列表
List<Integer> res = new ArrayList<>();
if(root == null) return res;
// 存放遍历到的节点的栈
Deque<TreeNode> stack = new LinkedList<TreeNode>();
while(!stack.isEmpty() || root != null){
while(root != null){
// 迭代往下访问左节点直到为空
stack.push(root);
root = root.left;
}
// 当节点不存在时,将上一个节点出栈并获取节点的值
root = stack.pop();
res.add(root.val);
// 访问其右节点
root = root.right;
}
return res;
}
三 迭代实现后序遍历
这里介绍的是反转法来迭代实现后序遍历,我们知道后序遍历顺序为左右中,所以我们如果得到了中左右的遍历顺序结果,通过反转的方法便可得到后序遍历结果。所以方法很简单,只需改造以下前序遍历,让他先访问右节点便好。最后把结果反转一下就得到后序遍历结果了。如下图所示:
具体实现代码如下:
public List<Integer> postorderTraversal(TreeNode root) {
// 存放遍历结果的列表
List<Integer> res = new ArrayList<>();
if(root == null) return res;
// 存放遍历到的节点的栈
Deque<TreeNode> stack = new LinkedList<>();
TreeNode node = root;
while(!stack.isEmpty() || node != null){
while(node != null){
// 一直迭代寻找右节点
res.add(node.val);
stack.push(node);
node = node.right;
}
// 若无右节点则出栈寻找其左节点
node = stack.pop();
node = node.left;
}
// 将得到的中右左的前序遍历结果反转则得到左右中的后序遍历结果
Collections.reverse(res);
return res;
}