正常的层序遍历是利用一个队列来完成,而倒序的层序遍历是利用一个队列加一个栈,都比较容易
那么考虑:1. 从上到下每一层都是从右往左输出
2.以及从下到上每一层都是从左往右输出的情况
该类问题的核心,我认为首先是判断换层的时机,就是需要判断何时换到了二叉树的下一层,其次是需要使用到双端队列来更改每层的出入顺序 ,应该不难求解
先解决情况2, 情况1就是同理,只不过1不需要使用栈,把入栈的地方换成直接输出就行了,更简单
主要是使用双端队列来完成将每层在队列的元素倒序入栈的效果
//以下是代码部分(以问题2为例):
void levelorder3(TreeNode *root){
deque<TreeNode*>q; //使用双端队列
stack<TreeNode*>s;
q.push_back(root);
while(!q.empty()){
int count = q.size();//count用来记录当前层的结点数,方便判断是否换层
while(count){ //循环结束即代表换层了
TreeNode *p = q.back(); //注意从队尾开始
q.pop_back(); //弹出队尾
s.push(p); //将队尾入栈
if(p->right){ //注意:这里要先让右子树从队头进入,可以画图思考
q.push_front(p->right);
}
if(p->left){
q.push_front(p->left);
}
count--;
}
}
while(s.size()){
TreeNode *t = s.top();
s.pop();
cout << t->val <<" ";
}
}
再来一个从上而下的“之”字形遍历(即左右交叉遍历)
void levelorder5(TreeNode *root){
//分析:需要判断层数,奇数层则从左向右输出,偶数层从右向左输出
//预期输出结果:ACBDE
deque<TreeNode*>q;
q.push_back(root);
int flag = 1;//用来判断当前是奇数层还是偶数层
while(!q.empty()){
int count = q.size();
while(count){
if(flag%2!=0){//奇数层正常从左到右即可
TreeNode *p = q.front();
q.pop_front();
cout << p->val <<" ";
if(p->left) q.push_back(p->left);
if(p->right) q.push_back(p->right);
}
else{//偶数层从右到左,因此从双端队列的尾部弹出元素,并且插入左右子树的时候也需要改变顺序
TreeNode *p = q.back();
q.pop_back();
cout << p->val << " ";
if(p->right) q.push_front(p->right);
if(p->left) q.push_front(p->left);
}
count--;
}
flag++;
}
}