zoukankan      html  css  js  c++  java
  • 队列 102 Binary Tree Level Order Traversal

    队列的基本应用 - 广度优先遍历

    1)树 : 层序遍历;

    2)图:无权图的最短路径。

    使用队列来实现二叉树的层序遍历,需要多关注一个层数的信息

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> levelOrder(TreeNode* root) {
            vector<vector<int> > res;   //存储最终输出的二维列表
            if(root == NULL)
                return res;
            queue< pair<TreeNode*, int> > q;    //将当前结点与它在第几层成对
            q.push(make_pair(root, 0));
            while(!q.empty()){
                TreeNode* node = q.front().first;
                int level = q.front().second;
                q.pop();
                
                if(level == res.size())  //若相等则说明res中还不存在这一层,因为level从0开始计数,res从1开始
                    //这个结点在一个新的层中,在res中新加一层
                    res.push_back(vector<int>());
                
                res[level].push_back(node->val);
                
                if(node->left)
                    q.push(make_pair(node->left, level+1));
                if(node->right)
                    q.push(make_pair(node->right, level+1));
            }
            return res;
        }
    };

    解法二:<推荐> 比解法一通用,更方便。

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> levelOrder(TreeNode* root) {
            if(!root) 
                return {};
            vector<vector<int>> res;
            queue<TreeNode* > q{{root}};
            while(!q.empty()){
                vector<int> oneLevel;
                for(int i = q.size(); i>0; i--){
                    //因为q的大小是会变的,所以i要从q.size()开始从大往小减
                    TreeNode* t = q.front();
                    q.pop();
                    oneLevel.push_back(t->val);
                    if(t->left) q.push(t->left);
                    if(t->right) q.push(t->right);
                }
                res.push_back(oneLevel);
            }
            return res;
        }
    };

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> levelOrderBottom(TreeNode* root) {
            if(!root) 
                return {};
            vector<vector<int>> res;
            queue<TreeNode* > q{{root}};
            while(!q.empty()){
                vector<int> oneLevel;
                for(int i = q.size(); i>0; i--){
                    TreeNode* t = q.front();
                    q.pop();
                    oneLevel.push_back(t->val);
                    if(t->left) q.push(t->left);
                    if(t->right) q.push(t->right);
                }
                res.insert(res.begin(), oneLevel);    //倒序插入
            }
            return res;
        }
    };

    之形的意思是:第0行是从左到右遍历,第1行是从右到左遍历,以此类推,交叉往返的之字形的层序遍历。

    这里需要注意的一点是:不能将某一层的左子树和右子树逆序插入,这样会导致下一层的顺序出错。而是应该在奇数层时将各个结点反向插入

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
            vector<vector<int> > res;
            if(!root)
                return {};
            queue<TreeNode* > q{{root}};
            int j = 0;   //层数从0开始计数
            while(!q.empty()){
                vector<int> oneLevel;
                for(int i=q.size(); i>0; i--){
                    TreeNode* t = q.front();
                    q.pop();
                    
                    if(j%2 == 0){
                        oneLevel.push_back(t->val);     //偶数层正向插入
                    }
                    else{
                        oneLevel.insert(oneLevel.begin(), t->val);   //奇数层时反向插入
                    }  
                    if(t->left) q.push(t->left);
                    if(t->right) q.push(t->right);
                }
                j++;
                res.push_back(oneLevel);
            }
            return res;
        }
    };

    即打印出二叉树每一行最右边的一个结点。使用队列来实现,遍历每层的结点时,把下一层的结点都存入队列中,则每当开始新一层结点的遍历之前,先把新一层最后一个结点值存到res中。

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<int> rightSideView(TreeNode* root) {
            vector<int> res;
            if(!root) return {};
            queue<TreeNode*> q{{root}};
            while(!q.empty()){
                res.push_back(q.back()->val);   //将每层的最后一个结点保存到res中
                for(int i=q.size(); i>0; i--){
                    TreeNode* t = q.front();
                    q.pop();
                    if(t->left) q.push(t->left);
                    if(t->right) q.push(t->right);
                }
            }
            
            return res;
        }
    };
  • 相关阅读:
    让你的 Python 代码优雅又地道
    Python3简单爬虫抓取网页图片
    Python 全集变量
    python-ConfigParser模块【读写配置文件】
    Python 第三方插件库
    Python 安装 lxml 插件
    Python cmd中输入'pip' 不是内部或外部命令,也不是可运行的程序或批处理文件。
    SQLServer代理新建或者编辑作业报错
    Python pycharm 常用快捷键
    python 安装插件 requests、BeautifulSoup
  • 原文地址:https://www.cnblogs.com/Bella2017/p/10284540.html
Copyright © 2011-2022 走看看