Day18补档 二叉树 part02层序遍历

今日内容:
  • 层序遍历 10
  • 226.翻转二叉树
  • 101.对称二叉树 2

层序遍历

102. 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)

# 递归法
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        levels = []
        self.helper(root, 0, levels) #调用辅助函数,从根节点(层级为0)开始遍历
        return levels
    
    def helper(self, node, level, levels):
        if not node:
            return
        #如果当前层级等于层级列表的长度,说明这是一个新的层级,所以在层级列表中添加一个新的空列表
        if len(levels) == level: 
            levels.append([]) 
        #将当前节点的值添加到对应层级的列表中。
        levels[level].append(node.val) 

        #递归遍历左子树,层级加1。
        self.helper(node.left, level + 1, levels)
        #递归遍历右子树,层级加1。
        self.helper(node.right, level + 1, levels)

107. 二叉树的层序遍历 II

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

class Solution:
    def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        queue = collections.deque([root])
        result = []
        while queue:
            level=[]
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            result.append(level)
        return result[::-1]

二叉树输入 [3, 9, 20, null, null, 15, 7] 和代码片段的分析,让我来进一步解释这个过程:

  1. 初始时,队列 queue 中只有根节点 3。进入第一次循环:

    • 弹出节点 3,加入 3 的值到 level 中。
    • 发现节点 3 有左子节点 9,将 9 加入队列。
    • 发现节点 3 有右子节点 20,将 20 加入队列。
    • 此时 result 中为[3]
  2. 进入第二次循环,队列中的节点为 9 和 20

    • 弹出节点 9,加入 9 的值到 level 中。
    • 节点 9 没有左右子节点,不做处理。
    • 弹出节点 20,加入 20 的值到 level 中。
    • 发现节点 20 有左子节点 15,将 15 加入队列。
    • 发现节点 20 有右子节点 7,将 7 加入队列。
    • 此时 result 中为 [3, 9, 20]
  3. 进入第三次循环,队列中的节点为 15 和 7

    • 弹出节点 15,加入 15 的值到 level 中。
    • 节点 15 没有左右子节点,不做处理。
    • 弹出节点 7,加入 7 的值到 level 中。
    • 节点 7 没有左右子节点,不做处理。
    • 此时 result 中为 [3, 9, 20, 15, 7]
  4. 翻转result

199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*>que;
        if(root!=NULL) que.push(root);
        vector<int>result;
        while(!que.empty()){
            int size=que.size();
            for(int i=0;i<size;i++){
                TreeNode* node=que.front();
                que.pop();
                if(i==(size-1)) result.push_back(node->val);
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return result;

    }
};

637. 二叉树的层平均值

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

错误点:1、sum不能放在for循环里,2、result的数据类型不是int是double

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);
        vector<double> result;
        while(!que.empty()){
            int size=que.size();
            double sum=0;
            for(int i=0;i<size;i++){
                TreeNode* node=que.front();
                que.pop();
                sum+=node->val;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            result.push_back(sum / size); 
        }
        return result;
    }
};

429. N 叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

模板类型:记住子孩子节点的写法。

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*>que;
        if(root!=NULL) que.push(root);
        vector<vector<int>> result;
        int size=que.size();
        while(!que.empty()){
            int size=que.size();
            vector<int> vec;
            for(int i=0;i<size;i++){
                Node* node=que.front();
                que.pop();
                vec.push_back(node->val);
                for(int i=0;i<node->children.size();i++){
                   if(node->children[i]) que.push(node->children[i]);
                }
            }
            result.push_back(vec);
        }
        return result;
    }
};

515. 在每个树行中找最大值

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

条件 ? 表达式1 : 表达式2。这个运算符的工作原理如下:首先,它会计算条件表达式的结果。如果条件为真(非零),则运算符返回表达式1的值,否则返回表达式2

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);
        vector<int> result;
        while(!que.empty()){
            int size=que.size();
            int maxValue=INT_MIN;
            for(int i=0;i<size;i++){
                TreeNode* node=que.front();
                que.pop();
                maxValue = node->val > maxValue ? node->val : maxValue;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
            result.push_back(maxValue);
        }
        return result;
    }
};

116. 填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL

初始状态下,所有 next 指针都被设置为 NULL

class Solution {
public:
    Node* connect(Node* root) {
        queue<Node*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            // vector<int> vec;
            Node* nodePre;
            Node* node;
            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    nodePre = que.front(); // 取出一层的头结点
                    que.pop();
                    node = nodePre;
                } else {
                    node = que.front();
                    que.pop();
                    nodePre->next = node; // 本层前一个节点next指向本节点
                    nodePre = nodePre->next;
                }
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            nodePre->next = NULL; // 本层最后一个节点指向NULL
        }
        return root;

    }
};

假设我们有一个二叉树如下:

        1
      /   \
     2     3
    / \   / \
   4   5 6   7

我们运行这个函数,它会将每一层的节点通过next指针连接起来。下面是运行过程:

  1. 首先,将根节点1放入队列。

  2. 开始第一轮循环,队列中有1个节点,即1。因为这是第一个节点,所以nodePre和node都指向1,然后将1的左右子节点2和3放入队列。

  3. 结束第一轮循环,将1的next指针指向NULL。

  4. 开始第二轮循环,队列中有2个节点,即2和3。首先处理节点2,因为这是第一个节点,所以nodePre和node都指向2,然后将2的左右子节点4和5放入队列。接着处理节点3,node指向3,nodePre的next指向node,然后更新nodePre,将3的左右子节点6和7也放入队列。

  5. 结束第二轮循环,将3的next指针指向NULL。

  6. 开始第三轮循环,队列中有4个节点,即4、5、6和7。首先处理节点4,nodePre和node都指向4,然后将4的左右子节点(如果有的话)放入队列。接着处理节点5,node指向5,nodePre的next指向node,然后更新nodePre,将5的左右子节点(如果有的话)也放入队列。同样的方式处理节点6和7。

  7. 结束第三轮循环,将7的next指针指向NULL。

  8. 当队列为空时,结束整个过程。

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值