二叉树经典题之将二叉树分层打印

Posted 快乐江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树经典题之将二叉树分层打印相关的知识,希望对你有一定的参考价值。

前言:

二叉树刷题是有固定思维的,请移步

README】二叉树刷题框架

二叉树的层序遍历

题目

点击跳转:LeetCode

在这里插入图片描述

思路一:两个队列

分析:

如果直接让你层序遍历,那么就很简单,直接使用队列即可,但是现在它不止要求你层序遍历打印,而且还要求你同一层的要放在相同的一维vector里(C++中的数组),最终返回一个二维数组

思路一就是可以使用两个队列,queue_node队列用来保存二叉树的结点,queue_level用于标识某个结点属于那一层,因此其类型为int
整个过程和咋们层序遍历二叉树时的那个逻辑基本相似,不过就多了一个队列。比如下面这颗二叉树
在这里插入图片描述
首先先入根节点,同时保存层数的那个队列就入1,表示根节点处于第一层
在这里插入图片描述
然后出结点10,同时也出结点1,将其加入到结果中。出结点10的时候,再把9,8入队列,同时9,8由于是第二层,因为在queue_level中入两次2。
在这里插入图片描述
剩下的过程就是重复。

代码

虽然思路较为简单,但是代码还是有很多值得注意的地方,重点均标记在代码中

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        
        vector<vector<int>> ret;
        if(root==nullptr)//特判,空树直接返回
            return ret;
        vector<int> sub_ret;//二维数组中的一维数组
        
        queue<TreeNode*> queue_node;//保存结点的队列
        queue<int> queue_level;//保存结点的层数的队列
        
        int level=1;//变量level表示层数,默认从第一层开始
        
        TreeNode* temp;//中间变量temp,用接收从队列中弹出的结点
        queue_node.push(root);//首先将根节点加入
        queue_level.push(level);//根节点肯定属于第一层
        while(!queue_node.empty())//队列不空,就不断出队列
        {
            level=queue_level.front();//每结束第二个while循环,表示一层的已经搞完了,使用level更新此时的最新的层数
            while(level==queue_level.front())//把位于相同层的结点全部加入到sub_ret数组中
            {
                temp=queue_node.front();
                queue_node.pop();
                if(temp->left!=nullptr)//不要忘记每出一个结点就要把它的孩子几点给代入进来,先进左孩子,再进右孩子
                {
                    queue_node.push(temp->left);
                    queue_level.push(level+1);//进入一个孩子,这个孩子就是下一层了,所以要level+1
                }
                
                if(temp->right!=nullptr)
                {
                    queue_node.push(temp->right);
                    queue_level.push(level+1);
                }
                
                sub_ret.push_back(temp->val);//将同一层的结点全部加入到sub_ret中
                queue_level.pop();//queue_level也要记得出队列
            }

            ret.push_back(sub_ret);//内部while循环结束后,同一层的就完了,所以保存一层结果到ret中
            sub_ret.clear();//注意清空这个sub_ret,因为要重复利用到
 
        }
        return ret;
    }
};

在这里插入图片描述

思路二:变量控制

我们知道,在父节点出队列的时候,会把它的孩子带入到队列中,也就是队列的size本身保存的就是当前层的结点的个数,所以我们可以通过一个变量level去控制,让其一层一层的出。

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        vector<vector<int>> vv;
        if(root==nullptr)
            return vv;
        
        queue<TreeNode*> queue_node;
        queue_node.push(root);
        
        while(!queue_node.empty())
        {
            int level=queue_node.size();//一层一层的出,level保存的就是当前层的所有结点的个数
            vector<int> v;
            while(level--)
            {
                TreeNode* temp=queue_node.front();//出一个结点就把他的孩子结点带入进去
                queue_node.pop();
                v.push_back(temp->val);//同一层结点放进同一个一维数组中
                
                if(temp->left)
                    queue_node.push(temp->left);
                if(temp->right)
                    queue_node.push(temp->right);
            }
            vv.push_back(v);//一层完毕加入一个结果
        }
        
        return vv;
    }
};

在这里插入图片描述

以上是关于二叉树经典题之将二叉树分层打印的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer把二叉树打印成多行

二叉树经典题之二叉树最近公共祖先(LeetCode)

二叉树经典题之二叉树的非递归遍历

二叉树经典题之线索二叉树(中序)

二叉树经典题之根据二叉树创建字符串(二叉树的括号表示法)

经典面试题(十六)--二叉树的镜像