剑指offer 面试题32 二叉树的层序遍历

84 阅读2分钟

102. 二叉树的层序遍历 - 力扣(LeetCode)

我们可以先用queue先进先出的特性。

往queue里插入一个节点,然后弹出这个节点,用vector去接受这个节点。

然后再往queue里插入另一个节点,再弹出,vector再接受,循环往复。

直到vector里面已经存了整个树的节点为止。

但是这样的话vector打印出来就是整个样子:

image.png

但是我们想要的是这个样子:

image.png 也就是我们的vector应该按树层来存储节点

我们再创建一个二维vector,vector<vector>vv;

让vector每次存储每一树层的节点,如 (图c).

image.png 然后vector反馈给二维数组vv,这样vv就可以达到 (图b)的效果。

另外,如何保证刚好让vector每次都可以存储一层的节点呢。

可以用一个变量 levesize来统计下一层节点个数,v只要push_back levesize个节点就刚好够一层。

然后再给vv。

我写了这样的代码:
    class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
    
   queue<TreeNode*> q;
   vector<int> v;
   vector<vector<int>> vv;
    
    //if(root==NULL)return NULL;
      if(root) q.push(root);
      int levesize=1;
    
      while(!q.empty())
      {
          while(levesize--)
          {
                   TreeNode* Front=q.front();
          q.pop();
          v.push_back(Front->val);
          if(root->right)q.push(Front->left);
          if(root->right)q.push(Front->right);  


          }
   levesize=q.size();
   vv.push_back(v);
  }

  return vv;

    }
};

然后有一个报错:

image.png 这是因为我们应该去判断队列的下一层的左右子树是否为空,而不是去判断TreeNode: 因root在刚开始就判断过if(root==NULL)return vv; image.png

但是仍然有逻辑错误 :

image.png

可以明显地看出来是因为我们的 v没有清空导致的。 两种解决办法,一种是显示写v.pop_back() ,但是要自己控制弹出,如下就是仍然有报错的:

image.png 第二种方法就是我们隐式的方法,我们把vectorv放到while循环内部定义,这样出了作用域v 就会销毁。 整体代码如下:


class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
    
    
       queue<TreeNode*> q;//套用树模版来个队列
       vector<vector<int>> vv;//最后把遍历完的数据放到vv里
       int levesize=0;
    
       if(root) q.push(root);
       levesize=1;
  

    while(!q.empty())//当队列不为空时
    { vector<int> v;
      while(levesize--)
      {
         TreeNode* Front=q.front();
         q.pop(); 
         v.push_back(Front->val);
    
    
         if(Front->left) q.push(Front->left);
         if(Front->right) q.push(Front->right);
      }
      levesize=q.size();

   vv.push_back(v);
    }
        
        return vv;
    
    }
};