Leetcode 102. 二叉树的层序遍历

Leetcode 102. 二叉树的层序遍历

1、问题分析

题目链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
  本质上就是一个二叉树的遍历问题。代码我已经进行了详细的注释,理解应该没有问题,读者可以作为参考,如果看不懂(可以多看几遍),欢迎留言哦!我看到会解答一下。

2、问题解决

  笔者以C++方式解决。

#include "iostream"

using namespace std;

#include "algorithm"
#include "vector"
#include "queue"
#include "set"
#include "map"
#include "cstring"
#include "stack"

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;

    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
private:
    // 存储每一层节点,即层次数组
    // 例如 dp[1] 代表第 2 层的节点个数
    vector<vector<int>> dp;
    // 层次遍历使用的队列
    queue<TreeNode *> treeQueue;
    // 和上面的队列一一对应,只是这里存放的是节点对应的层数
    queue<int> layerQueue;
public:
    vector<vector<int>> levelOrder(TreeNode *root) {
        // 空树 直接返回空数组即可
        if (root == NULL) {
            return dp;
        }

        dealChen(root);
        return dp;
    }

    /**
     * 层序遍历
     * @param root
     */
    void dealChen(TreeNode *root) {
        //首先将根节点放入到队列中
        treeQueue.push(root);
        // 节点入队和层次入队都是一一对应的关系
        layerQueue.push(1);
        // 根节点就是一层,
        vector<int> temp;
        temp.push_back(root->val);
        // 将其保存到结果数组中
        dp.push_back(temp);

        // 初始化当前正在处理的层为 1
        int layerAll = 1;
        // 保存当前正在处理的层里面的节点值
        vector<int> temp_chen;
        while (!treeQueue.empty()) {
            // 取出队头元素
            TreeNode *pNode = treeQueue.front();
            // 获取该元素所在的层
            auto layerChen = layerQueue.front();

            // 如果该元素所在的层和当前正在处理的层不一样,说明已经进入下一层
            // 这时需要更新 当前处理的层,并将当前处理的层节点值 保存到结果数组
            // 同时清空当前处理的层
            if (layerChen != layerAll) {
                // 将当前处理的层节点值 保存到结果数组
                dp.push_back(temp_chen);
                // 同时清空当前处理的层
                temp_chen.clear();
                // 更新 当前处理的层为新节点的层
                layerAll = layerChen;
            }

            // 队头元素已经处理完毕,将其出队
            treeQueue.pop();
            layerQueue.pop();


            // 如果左子节点不为空,则入队
            if (pNode->left != NULL) {
                // 左子节点入队
                treeQueue.push(pNode->left);
                // 左子节点的层数入队,子节点的层数 就是 父节点层数 + 1
                layerQueue.push(layerChen + 1);
                // 当前处理的层节点值
                temp_chen.push_back(pNode->left->val);
            }

            // 原理和上面类似,只是左子节点变成右子节点
            // 如果右子节点不为空,则入队
            if (pNode->right != NULL) {
                // 右子节点入队
                treeQueue.push(pNode->right);
                // 右子节点的层数入队,子节点的层数 就是 父节点层数 + 1
                layerQueue.push(layerChen + 1);
                // 当前处理的层节点值
                temp_chen.push_back(pNode->right->val);
            }

        }
    }
};

int main() {

    TreeNode *pNode3 = new TreeNode(3);
    TreeNode *pNode9 = new TreeNode(9);
    TreeNode *pNode10 = new TreeNode(10);
    TreeNode *pNode8 = new TreeNode(8);
    TreeNode *pNode20 = new TreeNode(20);
    TreeNode *pNode15 = new TreeNode(15);
    TreeNode *pNode7 = new TreeNode(7);

    pNode3->left = pNode9;
    pNode3->right = pNode20;

    pNode20->left = pNode15;
    pNode20->right = pNode7;

    pNode9->left = pNode8;
    pNode9->right = pNode10;


    Solution *pSolution = new Solution;
    auto vector1 = pSolution->levelOrder(pNode3);

    for (int i = 0; i < vector1.size(); ++i) {
        for (int j = 0; j < vector1[i].size(); ++j) {
            cout << vector1[i][j] << " ";
        }
        cout << endl;
    }

    system("pause");
    return 0;
}

运行结果

在这里插入图片描述
有点菜,有时间再优化一下。

3、总结

  难得有时间刷一波LeetCode, 这次做一个系统的记录,等以后复习的时候可以有章可循,同时也期待各位读者给出的建议。算法真的是一个照妖镜,原来感觉自己也还行吧,但是算法分分钟教你做人。前人栽树,后人乘凉。在学习算法的过程中,看了前辈的成果,受益匪浅。
感谢各位前辈的辛勤付出,让我们少走了很多的弯路!
哪怕只有一个人从我的博客受益,我也知足了。
点个赞再走呗!欢迎留言哦!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值