力扣刷题二叉树前中后序遍历
Posted 王六六的IT日常
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣刷题二叉树前中后序遍历相关的知识,希望对你有一定的参考价值。
二叉树遍历系列
- 前序遍历:打印 - 左 - 右
- 中序遍历:左 - 打印 - 右
- 后序遍历:左 - 右 - 打印
在树的深度优先遍历中(包括前序、中序、后序遍历),递归方法最为直观易懂,但考虑到效率,我们通常不推荐使用递归。
1. 力扣 - 二叉树的前序遍历
递归:
递归思路:先树根,然后左子树,然后右子树。每棵子树递归。
class Solution
public List<Integer> preorderTraversal(TreeNode root)
//前序遍历 根左右
List<Integer> res = new ArrayList<>();
preOrder(root,res);
return res;
//前序遍历
public void preOrder(TreeNode root, List<Integer> res)
if(root == null)
return;
//打印-左-右
res.add(root.val);
preOrder(root.left,res);
preOrder(root.right,res);
迭代:
在迭代算法中,思路演变成,每到一个节点 A,就应该立即访问它。
因为,每棵子树都先访问其根节点。对节点的左右子树来说,也一定是先访问根。
在 A 的两棵子树中,遍历完左子树后,再遍历右子树。
因此,在访问完根节点后,遍历左子树前,要将右子树压入栈。
思路:
栈S;
p= root;
while(p || S不空)
while(p)
访问p节点;
p的右子树入S;
p = p的左子树;
p = S栈顶弹出;
class Solution
public List<Integer> preorderTraversal(TreeNode root)
//创建Integer类型的结果列表对象
List<Integer> res = new ArrayList<>();
if(root == null)
return res;
//创建类型为TreeNode的栈对象
Stack<TreeNode> stack = new Stack<>();
//根节点入栈
stack.add(root);
while(!stack.isEmpty())
//栈顶元素出栈(栈为先进后出,所以右孩子先入栈)
TreeNode cur = stack.pop();
//将此节点的值加入结果中
res.add(cur.val);
//判断该节点的右孩子是否为空
if(cur.right != null)
//右孩子入栈
stack.add(cur.right);
//判断该节点的左孩子是否为空
if(cur.left != null)
//左孩子入栈
stack.add(cur.left);
return res;
2. 力扣 - 二叉树中序遍历
递归:
递归的调用过程是不断往左边走,当左边走不下去了,就打印节点,并转向右边,然后右边继续这个过程。
class Solution
public List<Integer> inorderTraversal(TreeNode root)
List<Integer> result = new ArrayList<>();
//递归调用
inOrder(root,result);
return result;
//中序遍历
public void inOrder(TreeNode root,List<Integer> result)
if(root == null)
return;
//左
inOrder(root.left,result);
//打印
result.add(root.val);
//右
inOrder(root.right,result);
迭代:
用栈模拟递归过程
class Solution
public List<Integer> inorderTraversal(TreeNode root)
//迭代
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
//模拟递归
while(!stack.isEmpty()||root!= null)
//不断往左子树方向走,每走一次就将当前节点保存到栈中
//这是模拟递归的调用
if(root != null)
stack.add(root);
root = root.left;
//当前节点为空,说明左边走到头了,从栈中弹出节点并保存
//然后转向右边节点,继续上面整个过程
else
//直到没有左孩子
TreeNode cur = stack.pop();
res.add(cur.val);
root = cur.right;
return res;
3. 力扣 - 二叉树的后序遍历
左-右-打印
递归:
class Solution
public List<Integer> postorderTraversal(TreeNode root)
List<Integer> res = new ArrayList<>();
postOrder(root,res);
return res;
public void postOrder(TreeNode root,List<Integer> res)
if(root == null)
return;
postOrder(root.left,res);
postOrder(root.right,res);
res.add(root.val);
迭代:
每到一个节点 A,就应该立即访问它。
然后将左子树压入栈,再次遍历右子树。遍历完整棵树后,结果序列逆序即可。
思路:
栈S;
p= root;
while(p || S不空)
while(p)
访问p节点;
p的左子树入S;
p = p的右子树;
p = S栈顶弹出;
结果序列逆序;
class Solution
public List<Integer> postorderTraversal(TreeNode root)
//后序遍历:左右根
//前序遍历:根左右---反转---->左右根
List<Integer> res = new ArrayList<>();
if(root == null)
return res;
Stack<TreeNode> stack = new Stack<>();
//入栈
stack.push(root);
//栈不为空
while(!stack.isEmpty())
TreeNode cur = stack.pop();
res.add(cur.val);
//一直到左孩子为空跳出该循环
if(cur.left != null)
stack.push(cur.left);
if(cur.right != null)
stack.push(cur.right);
//反转数组
Collections.reverse(res);
return res;
以上是关于力扣刷题二叉树前中后序遍历的主要内容,如果未能解决你的问题,请参考以下文章