不使用递归方法返回二叉树的前中后序遍历数组
94. Binary Tree Preorder Traversal
用栈,从根结点开始将每次访问到的结点加入返回队列并加入栈中,然后对该结点的左子结点循环上述步骤,只到没有左子结点后,从栈中弹出一个结点,并开始访问该结点的右子树,设立p结点的目的就是为了在循环过程中跳过已经访问过的结点:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode p = root;
while (p != null || !stack.isEmpty()) {
while (p != null) {
res.add(p.val);
stack.add(p);
p = p.left;
}
TreeNode curr = stack.pop();
p = curr.right;
}
return res;
}
144. Binary Tree Inorder Traversal
和前序差不多,返回队列添加结点的位置变了而已:
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode p = root;
while (p != null || !stack.isEmpty()) {
while (p != null) {
stack.add(p);
p = p.left;
}
TreeNode current = stack.pop();
res.add(current.val);
p = current.right;
}
return res;
}
145. Binary Tree Postorder Traversal
稍微难一点,因为用前两道题的思路的话在有右子树的情况下中间结点就无法访问到了,但是
用前序遍历的思路但是访问顺序是 中间 -> 右子树 -> 左子树的话就可以得到后序遍历的倒序了,这里返回列表用LinkedList是因为它能用头插法加入新结点,这样得到的列表就不用再反转了:
public List<Integer> postorderTraversal(TreeNode root){
LinkedList<Integer> res = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode p = root;
while (p != null || !stack.isEmpty()) {
while (p != null) {
res.addFirst(p.val);
stack.push(p);
p = p.right;
}
TreeNode curr = stack.pop();
p = curr.left;
}
return res;
}