【剑指offer】19.按之字形顺序打印二叉树

总目录:

算法之旅导航目录

 

1.问题描述

给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
数据范围:0≤n≤1500,树上每个节点的val满足 ∣val∣<=1500
要求:空间复杂度:O(n),时间复杂度:O(n)

例如:
给定的二叉树是{1,2,3,#,#,4,5}

 

2.问题分析

 1层序迭代、辅助队列,每层迭代时按从左到右的顺序存储下一层节点,而打印本层节点时需要注意是否从左到右

2递归,用一个二维vector去接收每一层的节点值,递归完成后再按规则翻转相应层


3.代码实例

层序迭代,辅助队列

 1 /*
 2 struct TreeNode {
 3     int val;
 4     struct TreeNode *left;
 5     struct TreeNode *right;
 6     TreeNode(int x) :
 7             val(x), left(NULL), right(NULL) {
 8     }
 9 };
10 */
11 class Solution {
12   public:
13 
14     vector<vector<int> > Print(TreeNode* pRoot) {
15         vector<vector<int> > ret;
16         if(!pRoot){
17             return ret;
18         }
19 
20         queue<TreeNode*> nodeVec;//迭代存储每层节点
21         int nodeNumInLevel = 0; //当前层节点数量
22         bool isLeftToRight = true; //当前层的节点顺序
23         TreeNode* pCur = NULL;//哨兵节点
24 
25         nodeVec.push(pRoot);
26         while (!nodeVec.empty()) {
27             //接受打印
28             vector<int> curLevelVec;
29 
30             //逐个遍历当前层,存储节点
31             nodeNumInLevel = nodeVec.size();//取出当前层节点的数量
32             for (int i = 0; i < nodeNumInLevel; i++) {
33                 pCur = nodeVec.front();
34                 nodeVec.pop();
35 
36                 //循序插入还是逆序
37                 if (isLeftToRight) {
38                     curLevelVec.push_back(pCur->val);                    
39                 } else {
40                     curLevelVec.insert(curLevelVec.cbegin(), pCur->val);
41                 }
42 
43                 //按从左到右顺序存储下层节点
44                 if (pCur->left) nodeVec.push(pCur->left);
45                 if (pCur->right) nodeVec.push(pCur->right);
46             }
47             ret.push_back(curLevelVec);
48 
49             //翻转
50             isLeftToRight = !isLeftToRight;
51         }
52 
53         return ret;
54     }
55 };
View Code

递归

 1 /*
 2 struct TreeNode {
 3     int val;
 4     struct TreeNode *left;
 5     struct TreeNode *right;
 6     TreeNode(int x) :
 7             val(x), left(NULL), right(NULL) {
 8     }
 9 };
10 */
11 class Solution {
12   public:
13     void recurve(TreeNode* root, vector<vector<int>>& vec, int level) {
14         //中止条件
15         if (!root) {
16             return;
17         }
18 
19         //本层逻辑
20         //本层buffer尚未建立
21         if (vec.size() < level) {
22             vec.push_back(vector<int> {});
23         }
24         vec[level - 1].push_back(root->val);
25 
26         //调用递归
27         recurve(root->left, vec, level + 1);
28         recurve(root->right, vec, level + 1);
29 
30     }
31 
32     vector<vector<int>> Print(TreeNode* pRoot) {
33         vector<vector<int> > bufferVec;
34         if (!pRoot) {
35             return bufferVec;
36         }
37 
38         //进入迭代,获得的是每层都从左到右的打印
39         recurve(pRoot, bufferVec, 1);
40 
41         //new para
42         vector<vector<int> > retVec;
43         int levelNum = bufferVec.size();
44         int nodeNumInLevel = 0;
45         bool isLeftToRight = true;
46 
47         //按规则翻转
48         for (int i = 0; i < levelNum; i++) {
49             //新建vec
50             retVec.push_back(vector<int> {});
51 
52             //获取元素数量
53             nodeNumInLevel = bufferVec[i].size();
54             for (int j = 0; j < nodeNumInLevel; j++) {
55                 if(isLeftToRight){
56                     retVec[i].push_back(bufferVec[i][j]);                    
57                 }
58                 else{
59                     retVec[i].insert(retVec[i].cbegin(),bufferVec[i][j]);
60                 }
61             }
62             isLeftToRight = !isLeftToRight;
63         }
64         return retVec;
65     }
66 };
View Code

 

posted @ 2022-11-12 11:29  啊原来是这样呀  阅读(30)  评论(0)    收藏  举报