二叉树的前序遍历
class Solution { public 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) continue; ret.add(node.val); stack.push(node.right); stack.push(node.left); } return ret; } }
二叉树的后序遍历
class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> ret = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); stack.add(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; } }
后序遍历是:左右中
反过来是:中右左
所以中间的节点出栈以后,右边的先出栈,左边的最后出栈
所以入栈的顺序是node.left在node.right前面,后入先出,node.right先出栈
最后反转一下数组就得到后序遍历的数组
二叉树中序遍历
class Solution { public List<Integer> inorderTraversal(TreeNode root) { Stack<TreeNode> stack = new Stack<>(); List<Integer> list = new ArrayList<>(); while(root!=null){ stack.push(root); root = root.left; } while(!stack.isEmpty()){ TreeNode temp = stack.pop(); list.add(temp.val); temp = temp.right; while(temp!=null){ stack.push(temp); temp = temp.left; } } return list; } }
先不断地将左节点压入栈
while(root!=null){ stack.push(root); root = root.left; }
这个时候的stack的最上面的节点是最左的节点
然后再通过栈内元素进行迭代
while(!stack.isEmpty()){ TreeNode temp = stack.pop(); //栈顶的节点出栈 list.add(temp.val);//在压入右子树之前,处理它的数值部分 temp = temp.right;//获取它的右子树 while(temp!=null){//右子树存在,执行while循环 stack.push(temp);//压入当前节点 temp = temp.left;//不断压入左子节点 } }
当栈为空的时候,循环结束,因为会不断往栈内添加当前节点的