题解 | #按之字形顺序打印二叉树#
按之字形顺序打印二叉树
http://www.nowcoder.com/practice/91b69814117f4e8097390d107d2efbe0
题目的主要信息:
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)。
方法一:
层次遍历。用队列进行层次遍历,首先将根结点入队。通过一个循环,当队列不为空时,将队列中的元素逐个出列记录在ans中,同时每出列一个结点,就把该结点的左右孩子入列(如果有的话),这样能保证按照层次对树进行遍历,但是题目要求的是按照之字形顺序打印,实际上就是在偶数层翻转一下,因此用level记录层次,每当到达偶数层就翻转该层的结点。
具体做法:
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int>> res;//保存遍历结果
if (pRoot==NULL){//如果根为NULL
return res;
}
queue<TreeNode*> q;
q.push(pRoot);//根结点入列
int level = 0;//层
while (!q.empty()) {//层次遍历
int len = q.size();
vector<int> ans;//每一层的
for(int i = 0;i < len; i++) {
TreeNode *node = q.front();
q.pop();
ans.push_back(node->val);
if (node->left) q.push(node->left);//左孩子入列
if (node->right) q.push(node->right);//右孩子入列
}
level++;
if (level%2==0){ //偶数层是从右往左遍历
reverse(ans.begin(), ans.end());//将该层的值翻转
}
res.push_back(ans);
}
return res;
}
};
复杂度分析:
- 时间复杂度:,需要遍历一遍整个树。
- 空间复杂度:,队列大小为n。
方法二:
双栈法。首先明确栈的性质,存入栈中的顺序与从栈中输出的顺序相反。我们可以利用栈的这个性质进行交叉叫顺打印,用stack1保存奇数层的结点,stack2保存偶数层的结点。先把根结点放入stack1中,如果当前stack1不为空,说明当前层是奇数层,逐个输出栈顶元素,将输出结点的子女按照从左到右的顺序存入stack2中,这样能保证到达偶数层时,stack2中的出栈顺序为从右往左;当前层是偶数层,逐个输出栈顶元素,将输出结点的子女按照从右往左的顺序存入stack1中,这样能保证到达奇数层时,stack1中的出栈顺序为从左往右。将每层元素存入result中,最后返回result。 具体做法:
class Solution{
public:
vector<vector<int> > Print( TreeNode* pRoot){
vector<vector<int> > result;
if(pRoot==NULL){//根结点为NULL,返回空
return result;
}
stack<TreeNode*> stack1, stack2;
stack1.push(pRoot);//放入根结点
while(!stack1.empty() || !stack2.empty() ){
vector<int> ret1,ret2;
TreeNode* cur = NULL;
while( !stack1.empty()){//奇数层
cur = stack1.top();
//从左往右存子女到stack2中,stack2中出栈将以从右往左的顺序
if(cur->left) stack2.push(cur->left);
if(cur->right) stack2.push(cur->right);
ret1.push_back(stack1.top()->val);//保存本层所有结点值
stack1.pop();
}
if(ret1.size()) result.push_back(ret1);
while( !stack2.empty()){//偶数层
cur = stack2.top();
//从右往左存子女到stack1中,stack1中出栈将以从左往右的顺序
if(cur->right) stack1.push( cur->right);
if(cur->left) stack1.push( cur->left);
ret2.push_back(stack2.top()->val); //保存本层所有结点值
stack2.pop();
}
if(ret2.size()) result.push_back(ret2);
}
return result;
}
};
复杂度分析:
- 时间复杂度:,需要遍历一遍整个树。
- 空间复杂度:,栈大小为n。