一、二叉树的前序遍历
二叉树的前序遍历的顺序是中左右,所以呢,我们需要将在节点放进栈的时候就将节点的值放在数组中。我们可以一直遍历左子树,一直遍历无子树,然后从后往前,遍历右子树,这里我们可以倒推使用什么数据结构来存储节点,所以我们使用的是栈。
public static List<Integer> preOrderTraversal(treeNode root){
//存储结果的数组
List<Integer> res = new ArrayList<>();
//存储遍历过的节点,因为是向左向下遍历,之后需要原路返回遍历右子树,所以使用栈
Deque<treeNode> stack = new LinkedList<>();
treeNode n = root;
while(!stack.isEmpty() || n != null){
while(n != null){
res.add(n.val);
stack.push(n);
n = n.left;
}
n = stack.pop();
n = n.right;
}
return res;
}
二、二叉树的中序遍历
二叉树的中序遍历的顺序是左中右,所以我们从根节点出发遍历的时候不能直接将节点的值放入返回集合中,
public static List<Integer> preOrderTraversal(treeNode root){
//存储结果的数组
List<Integer> res = new ArrayList<>();
//存储遍历过的节点,因为是向左向下遍历,之后需要原路返回遍历右子树,所以使用栈
Deque<treeNode> stack = new LinkedList<>();
treeNode n = root;
while(!stack.isEmpty() || n != null){
while(n != null){
stack.push(n);
n = n.left;
}
n = stack.pop();
//和前序遍历的差别这条↓语句的位置发生了变化
res.add(n.val);
n = n.right;
}
return res;
}
三、二叉树的后序遍历
二叉树的后序遍历算法思想复杂,例如反转法、访问标记法、和Morris法。所以呢,我们采取了取巧的方式来得到二叉树的后序遍历结果。例如这颗二叉树。
他后序遍历的结果反转够来就是前序遍历的变式,只不过前序遍历是向左向下迭代,而这个变式是向右向下迭代。所以可以得到这个方法。
public static List<Integer> postOrderTraversal(treeNode root){
List<Integer> res = new ArrayList<>();
Deque<treeNode> stack = new LinkedList<>();
treeNode n = root;
while(!stack.isEmpty() || n != null){
while(n != null){
res.add(n.val);
stack.push(n);
n = n.right;
}
n = stack.pop();
n = n.left;
}
//别忘记了我们取巧得到的集合是后序遍历的反转,我们需要反转回来才能得到后序遍历结果
Collections.reverse(res);
return res;
}