树的非递归遍历
二叉树的遍历很重要,在面试中,如果涉及到二叉树的遍历,通常会要求使用非递归的方式
下面是三种遍历的非递归实现
前序遍历
public static List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();//返回的数组
Stack<TreeNode> stack = new Stack<>();//栈用于存储
stack.push(root);//根节点入栈
while (!stack.isEmpty()) {//栈不空的时候进行循环
TreeNode node = stack.pop();
if(node!=null) {
ret.add(node.val);//当前节点添加进入数组//先将右子树压入栈,保证出栈时是左子树先出来
stack.push(node.right);
stack.push(node.left);
}
}
return ret;
}
后续遍历
public static List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ret=new ArrayList<>();
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node=stack.pop();
if(node==null) continue;
ret.add(node.val);
stack.push(node.left);
stack.push(node.right);
}//前面的过程和前序遍历只要左右子树入栈顺序有差别,左子树先进,保证右子树先出
//最后将得到的数组逆序输出即可。因为原来的顺序是根-右-左,倒叙后才是真正的后续遍历结果
Collections.reverse(ret);return ret;
}
中序遍历
public static List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret=new ArrayList<>();
Stack<TreeNode> stack=new Stack<>();
TreeNode cur=root;
while (cur!=null||!stack.isEmpty()){//当前访问的节点不为空且栈不空的时候
while (cur!=null){
stack.push(cur);
cur=cur.left;
}//当cur是null,即是说到底了的时候
TreeNode node=stack.pop();
ret.add(node.val);//弹出元素的值入数组
cur=node.right;//cur更新为node.right
}
return ret;
}