剑指offer面试题32扩展 按 “之 ” 字形打印二叉树

46 阅读3分钟

按之字形顺序打印二叉树__牛客网 (nowcoder.com)

这道题我们可以这样解决,首先定义一个stack

因为stack是后进先出,所以如果遇到需要从右往左打印的树层,我们就让 left节点先入stackright节点后入stack

然后 right就会先弹出。

如果遇到需要从左到右打印的,正好入栈顺序相反。

而根据题目给的图我们可以看出,需要从右向左打印的是 偶数层,需要从左往右打印的是奇数层。

image.png

因此,我们只要偶数层从左往右入栈,奇数层从从右往左入栈即可。

    stack<TreeNode*> s;
    vector<vector<int>> vv;
    
    if(pRoot==NULL)return vv;
     s.push(pRoot);
     int LeveSize=1;
     int count=1;
     while(!s.empty())
     {
      vector<int> v;
      while(LeveSize--)
      {
           TreeNode* Front=s.top();
           s.pop();
           v.push_back(Front->val);
        count++;
          if(count%2==0)//偶数层
          {
          //从左往右
            if(Front->left)s.push( Front->left);
            if(Front->right) s.push(Front->right);
          }
           else
         {
           //奇数层从右往左
           if(Front->right)s.push( Front->right);
           if(Front->left)s.push(Front->left);
         }
    }
      LeveSize=s.size();
      vv.push_back(v);
     }
return vv;

但是运行之后结果不对: image.png

这里为什么会这样,剑指offer中有解释:

image.png image.png

拿我们的具体情况看,是这个样子:

image.png

因此会出现3和4排在一起的问题:

image.png

所以我们需要两个栈。

第一个栈 s[cur] 第二个栈 s[next]

s[cur] 不为空时:

image.png 此刻就不能再往 s[cur]里面插入数值了,应该往 第二个栈s[next]里插入:

image.png

同理,当 s[next]不为空时,应该往s [cur]里插入。

第二种思路:

设两个栈,s1存放奇数层,s2存放偶数层

遍历s1节点的同时按照左子树、右子树的顺序加入s2,

遍历s2节点的同时按照右子树、左子树的顺序加入s1

vector<vector<int> > Print(TreeNode* pRoot) {
    // write code here

    vector<vector<int>> vv;
    if (pRoot == NULL)return vv;

    stack<TreeNode*> s[2];
    int cur = 0;
    int next = 1;


    s[cur].push(pRoot);

    int LeveSize = 1;

    int count = 1;
    while (!s[cur].empty() && s[next].empty()) {
      vector<int> v;
     
        while (!s[cur].empty()) {
          TreeNode* Front = s[cur].top();
          s[cur].pop();
          v.push_back(Front->val);
          count++;
            if (Front->left)s[next].push( Front->left);
            if (Front->right) s[next].push(Front->right);
        }
         

        while (!s[next].empty()) {
          TreeNode* Front1 = s[next].top();
          s[next].pop();
          v.push_back(Front1->val);
          {
            if (Front1->right)s[cur].push( Front1->right);
            if (Front1->left)s[cur].push(Front1->left);
          }
        
      }
  return vv;
}
};

需要手动写一下清楚v内容,不然会有如下报错: image.png

手动清除:

/**
 * struct TreeNode {
 *  int val;
 *  struct TreeNode *left;
 *  struct TreeNode *right;
 *  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
 public:
  /**
   * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
   *
   *
   * @param pRoot TreeNode类
   * @return int整型vector<vector<>>
   */
  vector<vector<int> > Print(TreeNode* pRoot) {
    // write code here


    vector<vector<int>> vv;
    if (pRoot == NULL)return vv;

    stack<TreeNode*> s[2];
    int cur = 0;
    int next = 1;


    s[cur].push(pRoot);

    int LeveSize = 1;

    int count = 1;
    while (!s[cur].empty() && s[next].empty()) {
      vector<int> v;
     
        while (!s[cur].empty()) {
          TreeNode* Front = s[cur].top();
          s[cur].pop();
          v.push_back(Front->val);
          count++;
            if (Front->left)s[next].push( Front->left);
            if (Front->right) s[next].push(Front->right);
        }
          if(v.size()){
               vv.push_back(v);
                v.clear();
            }

        while (!s[next].empty()) {
          TreeNode* Front1 = s[next].top();
          s[next].pop();
          v.push_back(Front1->val);
          {
            if (Front1->right)s[cur].push( Front1->right);
            if (Front1->left)s[cur].push(Front1->left);
          }
        
      }
     // LeveSize = s[cur].size();
      // vv.push_back(v);
      if(v.size()){
               vv.push_back(v);
                v.clear();
            }
    }
  
  return vv;

}
};

image.png