类比上题 层序遍历
使用一个双端队列来维护输出顺序,其他同普通层序遍历一样
结点插入队列的顺序还是一样的,先左子树,后右子树。只是在插入值的时候,如果是从左向右那么从双端队列尾部插入,如果是从右向左,则把值从双端队列头部插入。从头部插入的,最后输出的时候正好先进的后出,后进的先出,达到了从右向左遍历的目的。
总之就是,在普通层序遍历的时候,每层我们都是从左至右遍历输出的,而在锯齿形层序遍历(之字形)中,奇数层(假设树根节点在0层)从右至左,而偶数层依旧是从左至右,所以我们只需处理奇数层即可,将从左至右反过来,先遍历的最后输出即达到了从右至左的目的。
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode():val(0),left(nullptr),right(nullptr){}
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
TreeNode(int x,TreeNode *left, TreeNode *right):val(x),left(left),right(right){}
};
//vector::end() 函数返回一个指向当前vector末尾元素的下一位置的迭代器.
//注意,如果你要访问末尾元素,需要先将此迭代器自减1.
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode *root) {
vector<vector<int> > vec;
if(root==nullptr)return vec;
queue<TreeNode *> que;
que.push(root);
bool flag = true;//true表示自左向右存,反之自右向左 对应双端队列就是尾插和头插
while(!que.empty()) {
int curLevelSize = que.size();
deque<int> levelList;
for(int i = 0;i<curLevelSize;i++) {
TreeNode *node = que.front();//取出队头元素
que.pop();//删除队头元素;
if(flag) {
levelList.push_back(node->val);
}else {
levelList.push_front(node->val);
}
if(node->left)que.push(node->left);
if(node->right) que.push(node->right);
}
//vec.emplace_back(vector<int>(levelList.begin(),levelList.end()));
vec.emplace_back(vector<int>{levelList.begin(), levelList.end()});
flag = !flag;
}
return vec;
}
};