C++算法:队列与BFS

队列与BFS

1.N叉树的层序遍历

使用BFS,即宽度优先搜索。把节点放入队列中,当节点出队列时让其孩子节点入队列,记录每层节点数量。

cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(Node* root)
    {
        vector<vector<int>> ret;
        queue<Node*> q;
        if (root == nullptr)
            return ret;
        q.push(root);
        while (!q.empty())
        {
            vector<int> v;
            int len = q.size(); //当前层节点数量
            for (int i = 0;i < len;i++)
            {
                Node* p = q.front();
                q.pop();
                v.push_back(p->val);

                for (Node* child : p->children)//下一层节点入队列
                    if (child != nullptr)
                        q.push(child);
            }
            ret.push_back(v);
        }
        return ret;
    }
};

2.二叉树的锯齿形层序遍历

与上一题相似,锯齿形层序遍历时,可以照常从左到右遍历,把第一层记为level=1,每偶数层时逆序数组即可。也可以使用别的方法,只要能在偶数层逆序即可。

cpp 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root)
    {
        vector<vector<int>> ret;
        queue<TreeNode*> q;
        int flag = 1;  // 规定flag<0小于时逆序数组。
        if (root == nullptr)
            return ret;
        q.push(root);
        while (!q.empty())
        {
            int len = q.size();
            vector<int> v;
            for (int i = 0;i < len;i++)
            {
                TreeNode* p = q.front();
                q.pop();
                v.push_back(p->val);

                if (p->left)
                    q.push(p->left);
                if (p->right)
                    q.push(p->right);
            }
            if (flag < 0) //判断是否逆序数组
                reverse(v.begin(), v.end());
            flag *= -1;
            ret.push_back(v);
        }
        return ret;
    }
};

3.二叉树最大宽度

根据题意,如果直接按照前面题目的模板,会出现超出内存限制的情况。如下图所示,3000个节点分别位于两侧,中间全为空节点。

此时可以考虑树的顺序存储。即给树的每个节点从左到右,从上到下编号,如果从1开始编号,某个节点下标为x,则它的孩子节点为2x和2x+1。依旧使用循环+队列的模板,非空节点入队列,队列元素应使用pair类型,记录节点及其下标,每次循环取队头和队尾的下标做差再加1,即可求出一层的宽度。

题目保证最终的宽度在32位带符号的整数范围内,如果用int做差返回的宽度错误,用unsigned int则能够正确返回宽度。

cpp 复制代码
class Solution {
public:
    int widthOfBinaryTree(TreeNode* root)
    {
        queue<pair<TreeNode*, unsigned int>> q;
        unsigned int ret = 0;
        q.push({ root,1 });
        while (!q.empty())
        {
            auto e1 = q.front();
            auto e2 = q.back();
            ret = max(ret, e2.second - e1.second + 1);
            size_t len = q.size();
            for (int i = 0;i < len;i++)
            {
                auto p = q.front();
                q.pop();
                if (p.first->left)
                    q.push({ p.first->left,p.second * 2 });
                if (p.first->right)
                    q.push({ p.first->right,p.second * 2 + 1 });
            }
        }
        return ret;
    }
};

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

与1、2题类似。只需用一个变量在遍历时记录最大值即可。

cpp 复制代码
class Solution {
public:
    vector<int> largestValues(TreeNode* root)
    {
        queue<TreeNode*> q;
        vector<int> ret;
        if (root == nullptr)
            return ret;
        q.push(root);
        while (!q.empty())
        {
            int Max = INT_MIN;
            size_t len = q.size();
            for (int i = 0;i < len;i++)
            {
                TreeNode* p = q.front();
                q.pop();
                if (Max < p->val)
                    Max = p->val;

                if (p->left)
                    q.push(p->left);
                if (p->right)
                    q.push(p->right);
            }
            ret.push_back(Max);
        }
        return ret;
    }
};
相关推荐
小小龙学IT10 分钟前
DuckDB 深度实战:用 C++ 在进程内跑一个「分析型数据库」
数据库·c++
知无不研1 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
2501_906565122 小时前
数学之美探究
算法
oier_Asad.Chen2 小时前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
C++ 老炮儿的技术栈3 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
leisoo80974 小时前
财报数据怎么排雷本地化Python构建财务异常预警系统
人工智能·python·算法
qz_Serene5 小时前
C++:类和对象(上)
开发语言·c++
luj_17686 小时前
塔防牌:策略与卡牌的智慧碰撞
服务器·c语言·开发语言·经验分享·算法
郝学胜-神的一滴6 小时前
干货版《算法导论》17:二叉树核心原理、遍历逻辑与高阶实操全解
数据结构·c++·python·算法·计算机·编程
爱编程的小新☆7 小时前
【LeetCode】从递归到 Flood Fill:5 道题吃透 DFS 的选择、回溯与标记
java·算法·leetcode·深度优先·回溯·flood fill