代码随想录算法训练营第十二天| 94. 二叉树的中序遍历 144. 二叉树的前序遍历 145. 二叉树的后序遍历 102.二叉树的层序遍历
Leetcode 94. 二叉树的中序遍历
题目链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/
题目描述:
-
-
给定一个二叉树的根节点
root
,返回 它的 中序 遍历 。示例 1:
输入:root = [1,null,2,3] 输出:[1,3,2]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [1] 输出:[1]
提示:
- 树中节点数目在范围
[0, 100]
内 -100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
- 树中节点数目在范围
-
思路:
1、递归
2、迭代
3、统一迭代(无需中序遍历设置特殊)
图示:
代码1:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
// 递归
List<Integer> res = new ArrayList<>();
midOrder(root,res);
return res;
}
public void midOrder(TreeNode root , List<Integer> res){
if(root == null) return;
// 左
midOrder(root.left,res);
// 中
res.add(root.val);
// 右
midOrder(root.right,res);
}
}
代码2:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
// 迭代
// 因为处理顺序和访问顺序是不一致的,所以需要借助指针来访问节点
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()){
if (cur != null){
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
result.add(cur.val);
cur = cur.right;
}
}
return result;
}
}
代码3:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
// 统一迭代法 中左右==》右左中
List<Integer> res = new ArrayList<>();
Stack<TreeNode> st = new Stack<>();
if(root!=null) st.push(root);
while(!st.isEmpty()){
TreeNode node = st.peek();
if(node!=null){
st.pop();
if(node.right!=null) st.push(node.right);
st.push(node);
st.push(null);
if(node.left!=null) st.push(node.left);
}else{
st.pop();
node = st.peek();
st.pop();
res.add(node.val);
}
}
return res;
}
}
总结:
递归和统一迭代都只是改变前中后的顺序就可以实现,迭代法的中序遍历处理顺序和访问顺序是不一致的。
Leetcode 144. 二叉树的前序遍历
题目链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/description/
题目描述:
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
- 树中节点数目在范围
[0, 100]
内 -100 <= Node.val <= 100
**进阶:**递归算法很简单,你可以通过迭代算法完成吗?
思路:
1、递归
2、迭代
3、统一迭代(无需中序遍历设置特殊)
图示:
代码1:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
// 使用递归
public List<Integer> preorderTraversal(TreeNode root) {
// 中左右
List<Integer> res = new ArrayList<Integer>();
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);
}
}
代码2:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
// 迭代
Stack<TreeNode> stack = new Stack<>();
List<Integer> res = new ArrayList<>();
if(root == null) return res;
stack.push(root);
while(!stack.isEmpty()){
// 因为用的元素是栈,所以要中右左
TreeNode node = stack.pop();
res.add(node.val);
if(node.right != null){
stack.push(node.right);
}
if(node.left!=null){
stack.push(node.left);
}
}
return res;
}
}
代码3:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Stack<TreeNode> st = new Stack<>();
if (root != null) st.push(root);
while (!st.empty()) {
TreeNode node = st.peek();
if (node != null) {
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
st.push(node); // 添加中节点
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.peek(); // 重新取出栈中元素
st.pop();
result.add(node.val); // 加入到结果集
}
}
return result;
}
}
总结:
递归和统一迭代都只是改变前中后的顺序就可以实现,迭代法的中序遍历处理顺序和访问顺序是不一致的。
Leetcode 145. 二叉树的后序遍历
题目链接:https://leetcode.cn/problems/binary-tree-postorder-traversal/description/
给你一棵二叉树的根节点 root
,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点的数目在范围
[0, 100]
内 -100 <= Node.val <= 100
**进阶:**递归算法很简单,你可以通过迭代算法完成吗?
思路:
1、递归
2、迭代
3、统一迭代(无需中序遍历设置特殊)
图示:
代码1:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
// 递归法
List<Integer> res = new ArrayList<>();
lastOrder(root,res);
return res;
}
public void lastOrder(TreeNode root , List<Integer> res){
if(root == null) return;
// 左
lastOrder(root.left,res);
// 右
lastOrder(root.right,res);
// 中
res.add(root.val);
}
}
代码2:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
// 迭代
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
if(root == null) return res;
while(!stack.isEmpty()){
TreeNode node = stack.pop();
// 左右中
// ===中右左颠倒
res.add(node.val);
if(node.left != null){
stack.push(node.left);
}
if(node.right != null){
stack.push(node.right);
}
}
Collections.reverse(res);
return res;
}
}
代码3:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
// 统一迭代法 左右中 ==》 中右左
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if(root != null) stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.peek();
if(node!=null){
stack.pop();
stack.push(node);
stack.push(null);
if(node.right!=null) stack.push(node.right);
if(node.left != null) stack.push(node.left);
}else{
stack.pop();
node = stack.peek();
stack.pop();
res.add(node.val);
}
}
return res;
}
}
总结:
递归和统一迭代都只是改变前中后的顺序就可以实现,迭代法的中序遍历处理顺序和访问顺序是不一致的。
Leetcode 102.二叉树的层序遍历
题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal/description/
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
-
树中节点数目在范围
[0, 2000]
内 -
-1000 <= Node.val <= 1000
思路:
1、递归
2、借助队列
图示:
代码1:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
checkFun01(root,0);
return resList;
}
//BFS--递归方式
public void checkFun01(TreeNode node, Integer deep) {
if (node == null) return;
deep++;
if (resList.size() < deep) {
//当层级增加时,list的Item也增加,利用list的索引值进行层级界定
List<Integer> item = new ArrayList<Integer>();
resList.add(item);
}
resList.get(deep - 1).add(node.val);
checkFun01(node.left, deep);
checkFun01(node.right, deep);
}
}
代码2:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
// 队列存储节点
Dequestruct(root);
return resList;
}
// 借助队列
public void Dequestruct(TreeNode node){
if(node == null) return;
Queue<TreeNode> que = new LinkedList<>();
que.offer(node);
while(!que.isEmpty()){
List<Integer> itemList = new ArrayList<Integer>();
int len = que.size();
while(len>0){
TreeNode tempNode = que.poll();
itemList.add(tempNode.val);
if(tempNode.left != null) que.offer(tempNode.left);
if(tempNode.right != null) que.offer(tempNode.right);
len --;
}
resList.add(itemList);
}
}
}
总结:
后续更新相同类型的十道题
resList;
}
// 借助队列
public void Dequestruct(TreeNode node){
if(node == null) return;
Queue que = new LinkedList<>();
que.offer(node);
while(!que.isEmpty()){
List itemList = new ArrayList();
int len = que.size();
while(len>0){
TreeNode tempNode = que.poll();
itemList.add(tempNode.val);
if(tempNode.left != null) que.offer(tempNode.left);
if(tempNode.right != null) que.offer(tempNode.right);
len --;
}
resList.add(itemList);
}
}
}
###### 总结:
后续更新相同类型的十道题