题目23:从上往下打印二叉树(leetcode链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/)
题目分析
方法1:
建立队列,利用队列的先进先出特点,将二叉树的节点入队,当每一个父节点出队时将其左右孩子节点入队,这样队列中的节点顺序就是按照从上向下从左向右的顺序打印的。
方法2:题目改进,使用二维数组返回结果,二叉树的每一层保存在二维数组的一项中(leetcode链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/submissions/)。
基本思路还是建立队列,让父节点出队时子节点入队。但是,这里需要建立一个临时数组保存每一层的节点,当每一层节点遍历完后在放入ret数组中,而确定每一层节点是否遍历完需要两个整型变量,一个保存当前层节点个数一个保存下一层节点个数,每当一个节点存入临时数组时,当前节点就-1,当当前节点为0表示这一层已经打印完径临时数组加入ret中,同时进行下一层遍历。
方法3:题目改进,当是奇数层按照从左向右打印偶数层按照从右向左打印。
基本思路和方法2相同,只是将临时数组加入到ret中时需要判断当前层时奇数层还是偶数层,如果是偶数层逆置数组在加入ret.
代码描述
方法2
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
vector<int> ret;
if(root == NULL)
return ret;
//创建队列对象
queue<TreeNode*> myQueue;
//根节点入队
myQueue.push(root);
while(!myQueue.empty())
{
//队头节点的左右孩子节点入队
if(myQueue.front()->left)
myQueue.push(myQueue.front()->left);
if(myQueue.front()->right)
myQueue.push(myQueue.front()->right);
//队头节点出队
ret.push_back(myQueue.front()->val);
myQueue.pop();
}
return ret;
}
};
方法2
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ret;
//如果二叉树为空,返回空数组
if(root == NULL)
return ret;
queue<TreeNode*> myQueue;
//根节点入队
myQueue.push(root);
//初始化临时变量和临时数组
int count1 = 1;//当前层节点个数
int count2 = 0;//下一层节点个数
int row = 0;//当前层数
vector<int> ret1;
while(!myQueue.empty())
{
//如果当前层数已经遍历完,count1就为0
if(count1 == 0)
{
//将临时数组加入ret中
ret.push_back(ret1);
//清空临时数组
while(!ret1.empty())
ret1.pop_back();
//更新当前层节点数,进入下一层
count1 = count2;
//更新下一层节点数
count2 = 0;
//更新层数
row++;
}
//获取队头节点存入临时数组中
ret1.push_back(myQueue.front()->val);
//每存入一个,当前层节点数-1
count1--;
//将队头节点的左右孩子节点入队
if(myQueue.front()->left)
{
myQueue.push(myQueue.front()->left);
//每箱队列中加入一个节点,下一层节点数+1
count2++;
}
if(myQueue.front()->right)
{
myQueue.push(myQueue.front()->right);
count2++;
}
//队头节点已经存入到临时数组中,将队头节点出队
myQueue.pop();
}
//如果临时数组中有还没有加入到ret中的,就要加入
if(!ret1.empty())
ret.push_back(ret1);
return ret;
}
};
方法3
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ret;
//如果二叉树为空,返回空数组
if(root == NULL)
return ret;
queue<TreeNode*> myQueue;
//根节点入队
myQueue.push(root);
//初始化临时变量和临时数组
int count1 = 1;//当前层节点个数
int count2 = 0;//下一层节点个数
int row = 0;//当前层数
vector<int> ret1;
while(!myQueue.empty())
{
//如果当前层数已经遍历完,count1就为0
if(count1 == 0)
{
//偶数行要反转数组从右向左打印
if(row%2 != 0)
{
vector<int>::iterator begin = ret1.begin();
vector<int>::iterator end = ret1.end()-1;
while(begin < end)
{
int tmp = *begin;
*begin = *end;
*end = tmp;
begin++;
end--;
}
}
//将临时数组加入ret中
ret.push_back(ret1);
//清空临时数组
while(!ret1.empty())
ret1.pop_back();
//清空临时数组
while(!ret1.empty())
ret1.pop_back();
//更新当前层节点数,进入下一层
count1 = count2;
//更新下一层节点数
count2 = 0;
//更新层数
row++;
}
//获取队头节点存入临时数组中
ret1.push_back(myQueue.front()->val);
//每存入一个,当前层节点数-1
count1--;
//将队头节点的左右孩子节点入队
if(myQueue.front()->left)
{
myQueue.push(myQueue.front()->left);
//每箱队列中加入一个节点,下一层节点数+1
count2++;
}
if(myQueue.front()->right)
{
myQueue.push(myQueue.front()->right);
count2++;
}
//队头节点已经存入到临时数组中,将队头节点出队
myQueue.pop();
}
//如果临时数组中有还没有加入到ret中的,就要加入
if(!ret1.empty())
{
if(row%2 != 0)
{
vector<int>::iterator begin = ret1.begin();
vector<int>::iterator end = ret1.end()-1;
while(begin < end)
{
int tmp = *begin;
*begin = *end;
*end = tmp;
begin++;
end--;
}
}
ret.push_back(ret1);
}
return ret;
}
};