LeetCode 二叉树的前、中、后序遍历(94、144、145)

二叉树的三种遍历方式(Java实现)

144. 二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

img

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

img

输入:root = [1,2]
输出:[1,2]

示例 5:

img

输入:root = [1,null,2]
输出:[1,2]

思路1(递归解法)

递归解法比较简单,也很常规,就不再多说思路了

public List<Integer> preorderTraversal(TreeNode root) {
    //新建一个链表
	List<Integer> list = new ArrayList<Integer>();
    
    if(root == null){
        return list;
    }
    
    preOrder(root, list);
    return list;
}

public void preOrder(TreeNode root, List<Integer> list){
    list.add(root.val);
    if(root.left != null){
        preOrder(root.left, list);
    }
    
    if(root.right != null){
        preOrder(root.right, list);
    }
}

思路2 (利用栈进行遍历)

步骤:

  1. 新建一个栈stack
  2. 将root放入栈中
  3. pop栈顶,将pop元素的右结点和左结点入栈
  4. 重复上述操作直到stack空

代码:

List<Integer> list = new ArrayList<Integer>();
if(root == null){
    return list;
}

Stack<TreeNode> stack = new Stack<TreeNode>();

stack.push(root);

while(!stack.isEmpty){
    TreeNode t = stack.pop();
    list.add(t.val);
    
    if(t.right != null){
        stack.push(t.right);
    }
    
    if(t.left != null){
        stack.push(t.left);
    }
}

return list;

思路3(迭代法遍历模板)

步骤:

  1. 创建一个栈stack和一个数组list
  2. 循环判断栈或者root结点是否均为空,如果满足则结束,否则进入步骤3
  3. 判断root结点是否为空,如果不为空则将root.val加入到list中,并令root入栈,并令root = root.left
  4. 令root = stack.pop().right,跳转至步骤2
//创建一个数组list
List<Integer> list = new ArrayList<Integer>();
if(root == null){
    return list;
}

//创建一个栈stack
Stack<TreeNode> stack = new Stack<TreeNode>();

//循环判断stack或者root均为空
while(!stack.isEmpty() || root != null){
    while(root != null){
        list.add(root.val);
        stack.push(root);
        root = root.left;
    }
    
    root = stack.pop().right;
}
return list;

94. 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历

示例 1:

img

输入:root = [1,null,2,3]
输出:[1,3,2]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

思路1(递归解法)

递归法比较简单

public void infixOrder(TreeNode root, List<Integer>list){
    if(root == null){
        return;
    }
    infixOrder(root.left, list);
    
    list.add(root.val);
    
    infixOrder(root.right, list);
}

public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> list = new ArrayList<Integer>();
    
    infixOrder(root, list);
    
    return list;
}

思路2 (迭代解法)

步骤:

  1. 创建一个栈stack和一个队列list
  2. 循环判断stack是否为空并且root为null,如果满足则结束循环,否则进入步骤3
  3. 循环判断root.left是否为空,若不为空则将结点root入栈,并且令root = root.left,即将左子结点全部入栈,当root为叶子结点时,结束循环
  4. 令root = stack.pop(),list.add(root.val),再令root = root.right, 返回步骤2
List<Integer> list = new ArrayList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();

while(!stack.isEmpty() || root != null){
    while(root != null){
        stack.push(root);
        root = root.left;
    }
    
    root = stack.pop();
    list.add(root.val);
    root = root.right;
}

return list;

145. 二叉树的后序遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历

示例 1:

img

输入:root = [1,null,2,3]
输出:[3,2,1]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

思路1(递归方法)

public List<Integer> postorderTraversal(TreeNode root) {
    List<Integer> list = new ArrayList<Integer>();
    
    postOrder(root, list);
    
    return list;
}

public void postOrder(TreeNode root, List<Integer> list){
    if(root == null){
        return;
    }
    
    postOrder(root.left, list);
    postOrder(root.right, list);
    list.add(root.val);
}

思路2 (迭代模板)

利用栈和一个辅助指针实现,步骤:

  1. 创建一个栈stack和一个数组list,并初始化辅助指针pre
  2. 循环判断stack为空并且root为空,若都满足则程序结束,否则进入步骤3
  3. 循环将root的左子节点压入栈,再令root = root.left,直到root指向null
  4. 令root = stack.pop()
  5. 如果结点的右子树为空或者右子树与pre相同,则将root存放的值加入到list中list.add(root.val),令pre指向root结点pre = root,否则将root压回到栈中。完成上述判断后,让root指向空root = null
  6. 返回步骤2直至程序结束,返回list
public List<Integer> postorderTraversal(TreeNode root) {
    //创建一个栈stack
    Stack<TreeNode> stack = new Stack<TreeNode>();
    //创建一个数组list
    List<Integer> list = new ArrayList<Integer>();
    //初始化辅助指针pre
    TreeNode pre;
    
    //循环判断栈stack和root是否均为空
    while(!stack.isEmpty() || root != null){
        //循环将左子节点压入栈
        while(root != null){
            stack.push(root);
            root = root.left;
        }
        
        root = stack.pop();
        if(root.right == null || root.right != pre){
            list.add(root.val);
            pre = root;
        }else{
            stack.push(root);
            root = root.right;
        }
        root = null;
    }
    
    return list;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值