二叉树遍历笔记
144. 二叉树的前序遍历
题目:给定一个二叉树的根节点 root ,返回其节点值的 前序遍历。
解题思路:
前序遍历顺序为:根节点 -> 左子树 -> 右子树。使用递归的方法,将当前节点值加入到结果列表中,然后递归遍历其左子节点,再递归遍历其右子节点。
代码:
class Solution {
public void traversal(TreeNode root, List<Integer> result) {
if (root == null) {
return;
}
result.add(root.val); // 访问根节点
traversal(root.left, result); // 递归遍历左子树
traversal(root.right, result); // 递归遍历右子树
}
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
traversal(root, result);
return result;
}
}
145. 二叉树的后序遍历
题目:给定一个二叉树的根节点 root ,返回其节点值的 后序遍历。
解题思路:
后序遍历顺序为:左子树 -> 右子树 -> 根节点。通过递归遍历左子树,然后递归遍历右子树,最后将当前节点值加入结果列表中。
代码:
class Solution {
public void traversal(TreeNode root, List<Integer> result) {
if (root == null) {
return;
}
traversal(root.left, result); // 递归遍历左子树
traversal(root.right, result); // 递归遍历右子树
result.add(root.val); // 访问根节点
}
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
traversal(root, result);
return result;
}
}
94. 二叉树的中序遍历
题目:给定一个二叉树的根节点 root ,返回其节点值的 中序遍历。
解题思路:
中序遍历顺序为:左子树 -> 根节点 -> 右子树。先递归遍历左子树,之后将当前节点值加入结果列表,再递归遍历右子树。
代码:
class Solution {
public void traversal(TreeNode root, List<Integer> result) {
if (root == null) {
return;
}
traversal(root.left, result); // 递归遍历左子树
result.add(root.val); // 访问根节点
traversal(root.right, result); // 递归遍历右子树
}
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
traversal(root, result);
return result;
}
}
二叉树遍历笔记(迭代法)
144. 二叉树的前序遍历(迭代法)
题目:给定一个二叉树的根节点 root ,返回其节点值的 前序遍历。
解题思路:
前序遍历顺序为:根节点 -> 左子树 -> 右子树。使用栈来模拟递归调用的过程,将根节点首先加入栈中,然后在每次迭代中将栈顶节点弹出并访问该节点,将右子节点和左子节点(如果存在)依次压入栈中,确保左子节点先于右子节点访问。
代码:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if (root == null) {
return result;
}
Stack<TreeNode> st = new Stack<>();
st.push(root);
while (!st.isEmpty()) {
TreeNode node = st.pop();
result.add(node.val);
if (node.right != null) st.push(node.right);
if (node.left != null) st.push(node.left);
}
return result;
}
}
145. 二叉树的后序遍历(迭代法)
题目:给定一个二叉树的根节点 root ,返回其节点值的 后序遍历。
解题思路:
后序遍历顺序为:左子树 -> 右子树 -> 根节点。可以先使用栈进行 根 -> 右 -> 左 的顺序遍历,将节点值添加到结果列表,然后将列表反转得到正确的后序遍历顺序。
代码:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if (root == null) {
return result;
}
Stack<TreeNode> st = new Stack<>();
st.push(root);
while (!st.isEmpty()) {
TreeNode node = st.pop();
result.add(node.val);
if (node.left != null) st.push(node.left);
if (node.right != null) st.push(node.right);
}
// Reverse the result list to get the correct order
int left = 0;
int right = result.size() - 1;
while (left < right) {
int temp = result.get(left);
result.set(left, result.get(right));
result.set(right, temp);
left++;
right--;
}
return result;
}
}
94. 二叉树的中序遍历(迭代法)
题目:给定一个二叉树的根节点 root ,返回其节点值的 中序遍历。
解题思路:
中序遍历顺序为:左子树 -> 根节点 -> 右子树。使用栈模拟递归过程,将所有左子节点依次压入栈中,直到遇到最左下的节点,然后出栈访问节点,并将其右子节点(如果存在)继续处理。
代码:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if (root == null) {
return result;
}
Stack<TreeNode> st = new Stack<>();
TreeNode node = root;
while (node != null || !st.isEmpty()) {
if (node != null) {
st.push(node);
node = node.left;
} else {
node = st.pop();
result.add(node.val);
node = node.right;
}
}
return result;
}
}
二叉树遍历笔记(统一迭代法)
144. 二叉树的前序遍历(统一迭代法)
题目:给定一个二叉树的根节点 root ,返回其节点值的 前序遍历。
解题思路:
采用统一迭代法,通过在每个节点前加入一个空节点标记。遇到节点时,将右子节点和左子节点依次压入栈,并将当前节点及一个空节点(用于标记访问)压入栈。遇到空节点时,弹出栈顶元素,将真正的节点值加入结果列表。
代码:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
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);
if (node.left != null) st.push(node.left);
st.push(node);
st.push(null);
} else {
st.pop();
node = st.pop();
result.add(node.val);
}
}
return result;
}
}
145. 二叉树的后序遍历(统一迭代法)
题目:给定一个二叉树的根节点 root ,返回其节点值的 后序遍历。
解题思路:
使用统一迭代法,在每个节点访问前添加空节点标记。首先将节点本身加入栈,再依次将其右子节点和左子节点压入栈。遇到空节点时,从栈中弹出真正的节点并将其值加入结果列表。
代码:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
Stack<TreeNode> st = new Stack<>();
if (root != null) {
st.push(root);
}
while (!st.isEmpty()) {
TreeNode node = st.peek();
if (node != null) {
st.pop();
st.push(node);
st.push(null);
if (node.right != null) st.push(node.right);
if (node.left != null) st.push(node.left);
} else {
st.pop();
node = st.pop();
result.add(node.val);
}
}
return result;
}
}
94. 二叉树的中序遍历(统一迭代法)
题目:给定一个二叉树的根节点 root ,返回其节点值的 中序遍历。
解题思路:
在中序遍历中,使用统一迭代法,通过在访问前加入空节点标记。将左子节点首先压入栈,空节点次之,再将右子节点压入栈。遇到空节点时,弹出栈顶元素,访问真正的节点并添加到结果列表。
代码:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = 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.pop();
result.add(node.val);
}
}
return result;
}
}
层序遍历
102.二叉树的层序遍历(opens new window)
题目:给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
解题思路:
代码:
class Solution {
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
checkFun01(root,0);
return resList;
}
public void checkFun01(TreeNode node,int deep){
if(node == null)return;
deep++;
if(resList.size()<deep){
List<Integer> item = new ArrayList<Integer>();
resList.add(item);
}
resList.get(deep-1).add(node.val);
checkFun01(node.left, deep);
checkFun01(node.right,deep);
}
public void checkFun02(TreeNode root){
if(root==null){
return;
}
Queue<TreeNode> que = new LinkedList<TreeNode>();
que.offer(root);
while(!que.isEmpty()){
List<Integer> item = new ArrayList<Integer>();
int size = que.size();
while(size>0){
TreeNode node = que.poll();
item.add(node.val);
if(node.left!=null)que.offer(node.left);
if(node.right!=null)que.offer(node.right);
size--;
}
resList.add(item);
}
}
}
107.二叉树的层次遍历II(opens new window)
题目:给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
解题思路:
代码:
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
// 利用链表可以进行 O(1) 头部插入, 这样最后答案不需要再反转
List<List<Integer>> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
List<Integer> levelList = new ArrayList<>();
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode peek = que.peekFirst();
levelList.add(que.pollFirst().val);
if (peek.left != null) {
que.offerLast(peek.left);
}
if (peek.right != null) {
que.offerLast(peek.right);
}
}
list.add(levelList);
}
List<List<Integer>> result = new ArrayList<>();
for (int i = list.size() - 1; i >= 0; i-- ) {
result.add(list.get(i));
}
return result;
}
}
199.二叉树的右视图(opens new window)
题目:给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
解题思路:
代码:
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
Queue<TreeNode> que = new LinkedList<TreeNode>();
if(root==null){
return result;
}
que.offer(root);
while(!que.isEmpty()){
int len = que.size();
TreeNode node = null;
while(len>0){
node = que.poll();
if(node.left!=null)que.offer(node.left);
if(node.right!=null)que.offer(node.right);
len--;
}
result.add(node.val);
}
return result;
}
}
637.二叉树的层平均值(opens new window)
题目:
解题思路:
代码:
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> result = new ArrayList<Double>();
Queue<TreeNode> que = new LinkedList<TreeNode>();
if(root==null){
return result;
}
que.offer(root);
while(!que.isEmpty()){
int len = que.size();
TreeNode node = null;
Double sum = 0.0;
int count = 0;
while(len>0){
node = que.poll();
if(node.left!=null)que.offer(node.left);
if(node.right!=null)que.offer(node.right);
len--;
sum = sum + node.val;
count++;
}
result.add(sum/count);
}
return result;
}
}
429.N叉树的层序遍历(opens new window)
题目:给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。
解题思路:
代码:
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> resList = new ArrayList<List<Integer>>();
if(root==null){
return resList;
}
Queue<Node> que = new LinkedList<Node>();
que.offer(root);
while(!que.isEmpty()){
List<Integer> item = new ArrayList<Integer>();
int size = que.size();
while(size>0){
Node node = que.poll();
if (node != null){
item.add(node.val);
List<Node> children = node.children;
for(Node child:children){
if(child!=null){
que.offer(child);
}
}
}
size--;
}
resList.add(item);
}
return resList;
}
}
515.在每个树行中找最大值(opens new window)
题目:您需要在二叉树的每一行中找到最大的值。
解题思路:
代码:
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
Queue<TreeNode> que = new LinkedList<TreeNode>();
if(root==null){
return result;
}
que.offer(root);
while(!que.isEmpty()){
int len = que.size();
TreeNode node = null;
int max = Integer.MIN_VALUE;
while(len>0){
node = que.poll();
if(node.left!=null)que.offer(node.left);
if(node.right!=null)que.offer(node.right);
len--;
if(node.val>max)max=node.val;
}
result.add(max);
}
return result;
}
}
116.填充每个节点的下一个右侧节点指针(opens new window)
题目:给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。
解题思路:
代码:
class Solution {
public Node connect(Node root) {
Queue<Node> que = new LinkedList<Node>();
if(root!=null){
que.add(root);
}
while(que.size() != 0){
int len = que.size();
Node node = que.poll();
if(node.left!=null)que.add(node.left);
if(node.right!=null)que.add(node.right);
while(len>1){
Node next = que.poll();
if(next.left!=null)que.offer(next.left);
if(next.right!=null)que.offer(next.right);
node.next = next;
node = next;
len--;
}
}
return root;
}
}
117.填充每个节点的下一个右侧节点指针II(opens new window)
题目:这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑一样的味道
解题思路:
代码:
class Solution {
public Node connect(Node root) {
Queue<Node> que = new LinkedList<Node>();
if(root!=null){
que.add(root);
}
while(que.size() != 0){
int len = que.size();
Node node = que.poll();
if(node.left!=null)que.add(node.left);
if(node.right!=null)que.add(node.right);
while(len>1){
Node next = que.poll();
if(next.left!=null)que.offer(next.left);
if(next.right!=null)que.offer(next.right);
node.next = next;
node = next;
len--;
}
}
return root;
}
}
104.二叉树的最大深度(opens new window)
题目:
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
解题思路:
代码:
class Solution {
public int maxDepth(TreeNode root) {
int result = 0;
Queue<TreeNode> que = new LinkedList<TreeNode>();
if(root==null){
return result;
}
que.offer(root);
while(!que.isEmpty()){
int len = que.size();
TreeNode node = null;
while(len>0){
node = que.poll();
if(node.left!=null)que.offer(node.left);
if(node.right!=null)que.offer(node.right);
len--;
}
result++;
}
return result;
}
}
111.二叉树的最小深度
题目:相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。
需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点
解题思路:
代码:
class Solution {
public int minDepth(TreeNode root) {
int result = 0;
Queue<TreeNode> que = new LinkedList<TreeNode>();
if(root==null){
return result;
}
que.offer(root);
while(!que.isEmpty()){
int len = que.size();
TreeNode node = null;
result++;
while(len>0){
node = que.poll();
if(node.left!=null)que.offer(node.left);
if(node.right!=null)que.offer(node.right);
if(node.left==null && node.right==null)return result;
len--;
}
}
return result;
}
}
2341

被折叠的 条评论
为什么被折叠?



