备战寒假实习,牛客刷题篇3
一、二叉树的前序遍历
给你二叉树的根节点 root ,返回它节点值的 前序 遍历
思路分析:
定义一个cur结点去遍历左子树,每遍历一个结点就将它放入栈中并且打印,直到左子树为空时。
从栈中弹出一个元素top,cur指向top的右子树.直到cur为空并且栈也为空时便不在循环。
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while(cur != null) {
stack.push(cur);
list.add(cur.val);
cur = cur.left;
}
TreeNode top = stack.pop();
cur = top.right;
}
return list;
} 二、二叉树的中序遍历
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
思路分析:
中序遍历与前序遍历思路大致相同,都是定义一个cur结点去遍历二叉树,不过中序遍历是一直将左子树放入stack中,直到左子树为空。
当左子树为空时,从stack中弹出一个结点,然后打印该节点,使cur指向top的右节点,直到cur为空并且栈也为空时便不在循环。
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while(cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode top = stack.pop();
list.add(top.val);
cur = top.right;
}
return list;
} 三、二叉树的后序遍历
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
思路分析:
后序遍历同样的,遍历二叉树,将每一个结点放入stack中,直到左子树为空时。
需要注意的是我们不是直接弹出栈,而是peek一下栈顶元素,这里我们就要分情况讨论了top的右子树是否为空,如果为空直接打印top元素,并且弹出,如果不为空那么使用cur指向top的右子树。
但这样我们的程序会出现一个bug,我们使cur指向top右节点后,将cur打印弹出后。
我们会发现程序又会使cur指向top右节点,这样无止的循环。
所以我们定义一个pre变量,prev用来定义上一次打印的结点,如果top的的右节点与prev结点相同时将不再遍历右节点,而直接打印top结点,并且stack弹出元素。
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
TreeNode prev = null;
while(cur != null || !stack.isEmpty()) {
while(cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode top = stack.peek();
if(top.right == null || top.right == prev) {
list.add(top.val);
stack.pop();
prev = top;
}else {
cur = top.right;
}
}
return list;
} #笔试成绩不好也能得到面试机会吗#
查看17道真题和解析
联想公司福利 1512人发布