Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
For example:
Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
return its level order traversal as:
[
[3],
[9,20],
[15,7]
]
二叉树基本操作,如果只是单纯的输出层序数列,那么一个queue就可以了,每次dequeue一个元素出来接着就把他的左右子树inqueue进去就行。这里要求层与层之间分开保存,所以需要增加些操作,这里提供两种方法,楼主也在之前的一篇博客里介绍过。栈和队列在二叉树遍历里的应用。
方法一:一个queue的实现
一个queue实现的时候,需要对每层的节点计数,从而完成分层的任务。计数的时候不用去按照理论上每层应该有的个数来判断,可以从根节点开始,弹出一个,本层数目减一,同时放进两个左右孩子,下一层数目加2。具体代码如下:
(1) 针对每层计数
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
vector<int> temp;
queue<TreeNode*> queuenode;
queuenode.push(root);
int nodesincurlevel = 1;
int nodesinnextlevel = 0;
while (!queuenode.empty()) {
TreeNode* curnode = queuenode.front();
queuenode.pop();
nodesincurlevel--;
if (curnode) {
temp.push_back(curnode->val);
queuenode.push(curnode->left);
queuenode.push(curnode->right);
nodesinnextlevel += 2;
}
if (nodesincurlevel == 0) {
//因为最后一层的时候temp会push进几个NULL,所以这里增加一下判断,否则res最后会有一项空的数组
if (temp.size() > 0) res.push_back(temp);
temp.clear();
nodesincurlevel = nodesinnextlevel;
nodesinnextlevel = 0;
}
}
return res;
}
(2)加间隔符
上一种方法里我们通过对每层计数的方法来实现,计数的时候同时计算NULL和实际node,为了保证在下一次检索的时候pop的都是上一层添加的孩子。这里也可以换一种思路,不添加NULL进队列,只添加确实存在的孩子,然后用NULL作为层与层之间的判断。
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
vector<int> part;
queue<TreeNode*> queueNode;
queueNode.push(root);
queueNode.push(NULL);
while (!queueNode.empty()) {
TreeNode* temp = queueNode.front();
queueNode.pop();
if (temp) {
part.push_back(temp->val);
if (temp->left) queueNode.push(temp->left);
if (temp->right) queueNode.push(temp->right);
}
else {
//一旦等于NULL意味着一层结束了,开始下一层
if (part.size() > 0) {
res.push_back(part);
part.clear();
queueNode.push(NULL);
}
}
}
return res;
}
方法二:两个queue实现
两个queue的话可以把当前的层与下一层分开push,等到当前层存储完成后与下一层交换即可。这里单独写了一个交换的函数,仅供参考。
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
vector<int> temp;
queue<TreeNode*> curlevel, nextlevel;
curlevel.push(root);
while (!curlevel.empty()) {
TreeNode* curNode = curlevel.front();
curlevel.pop();
if (curNode) {
temp.push_back(curNode->val);
nextlevel.push(curNode->left);
nextlevel.push(curNode->right);
}
if (curlevel.empty()) {
if (temp.size() > 0) res.push_back(temp);
temp.clear();
swap(curlevel, nextlevel);
}
}
return res;
}
void swap(queue<TreeNode*>& curlevel, queue<TreeNode*>& nextlevel) {
while (!nextlevel.empty()) {
TreeNode* temp = nextlevel.front();
nextlevel.pop();
curlevel.push(temp);
}
}
方法三:递归实现
在递归的时候纳入层的概念,不同层在res里的不同子序列中讨论。
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
helper(root, res, 0);
return res;
}
void helper(TreeNode* root, vector<vector<int>>& res, int level) {
if (root == NULL) return;
//如果是讨论的层数还没在res中开辟内存,则新建一个数组作为这一层的存储
if (res.empty() || level > res.size() - 1) {
res.push_back(vector<int>());
}
res[level].push_back(root->val);
levelOrder(root->left, res, level+1);
levelOrder(root->right, res, level+1);
}