二叉树的前中后序遍历以中间节点为基准,分布是:前序遍历:中左右;中序遍历:左中右;后序遍历:左右中;
递归解法的三要素:1.确定递归函数的参数和返回值
2.确定终止条件
3.判断每一层递归的处理逻辑
递归解法
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
preordertravel(root,list);
return list;
}
public void preordertravel(TreeNode cur,List<Integer> list){
if(cur==null){
return;
}
//中
list.add(cur.val);
//左
preordertravel(cur.left,list);
//右
preordertravel(cur.right,list);
}
}
中序遍历和后序遍历的递归代码类似,只是修改左中右处理语句的顺序即可
迭代解法
这里迭代解法中,使用栈来解决。首先遍历的节点和要处理的节点是一致的,要处理的节点是中间节点,也就是最开始的根节点。所以首先加入根节点,在遍历的时候,一开始就可以将要处理的节点加入数组中,然而栈是先入后出的,中左右的入栈顺序需要调换成中右左,出栈的时候就是中左右了,中间节点不需要做处理,因为一开始就将中间节点弹出保存了。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
ArrayDeque<TreeNode> stack=new ArrayDeque<>();
if(root==null){
return list;
}
stack.addFirst(root);
while(!stack.isEmpty()){
TreeNode node=stack.poll();
list.add(node.val);
if(node.right!=null){
stack.addFirst(node.right);
}
if(node.left!=null){
stack.addFirst(node.left);
}
}
return list;
}
}
后序遍历的迭代解法搭了前序遍历的顺风车,因为前序遍历中左右->中右左->左右中,经过两次顺序转换,就能达到后序遍历的效果
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
ArrayDeque<TreeNode> stack=new ArrayDeque<>();
if(root==null){
return list;
}
stack.addFirst(root);
while(!stack.isEmpty()){
TreeNode node=stack.poll();
list.add(node.val);//中
if(node.left!=null){
stack.addFirst(node.left);//左
}
if(node.right!=null){
stack.addFirst(node.right);//右
}
}
Collections.reverse(list);//中右左->左右中
return list;
}
}
中序遍历因为一开始遍历的节点和要处理的节点不同,所以不能用上面的方法,这里需要先找到要处理的节点,也就是没有左孩子的中间节点,加入数组后判断右孩子是否存在,若不存在,则直接弹出栈中元素,和递归有点类似。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
ArrayDeque<TreeNode> stack=new ArrayDeque<>();
TreeNode cur=root;
while(cur!=null||!stack.isEmpty()){
//先找到要处理的节点(中间节点)
while(cur!=null){
stack.addFirst(cur);
cur=cur.left;
}
//左孩子为空,找到了目标中间节点,加入数组中
cur=stack.poll();
list.add(cur.val);
//判断右孩子是否为空节点或者叶子节点,若为空节点,直接弹出栈顶中间节点
cur=cur.right;
}
return list;
}
}