面试题32:从上往下打印出二叉树的每个节点,同层节点从左至右打印。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root) { //传入指向根节点的指针
vector<int> Vprint; //存储待打印节点的数据域
//队列应该存整个节点,如果只是存放节点的数据域,则后面出对的时候无法通过指针找到左右子树,q中存放指向节点的指针
queue<TreeNode*> q;
if(root == nullptr) //空树时返回空序列
return Vprint;
q.push(root);
while(!q.empty()){
//每次出队某个节点时,分别将该节点的子节点入队,出队的元素存入Vector中,最后进行打印;
Vprint.push_back(q.front()->val); //每次将队首元素(节点的数据域)存入vector
if(q.front()->left != nullptr)
q.push(q.front()->left);
if(q.front()->right != nullptr)
q.push(q.front()->right);
q.pop(); //每次出队首元素
}
return Vprint; //将待打印的序列返回
}
};
拓展
如何广度遍历一副有向图?同样也可以基于队列实现。树是图的一种特殊退化形式,从上到下按层次遍历二叉树,从本质上来说就是广度优先遍历二叉树。
举一反三
题目二:分行从上到下打印二叉树。
题目三:之字形打印二叉树。
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路:
设两个栈,s1存放奇数层,s2存放偶数层
遍历s1节点的同时按照左子树、右子树的顺序加入s2,
遍历s2节点的同时按照右子树、左子树的顺序加入s1
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
//设两个栈,s1存放奇数层,s2存放偶数层
//遍历s1节点的同时按照左子树、右子树的顺序加入s2,
//遍历s2节点的同时按照右子树、左子树的顺序加入s1
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > Vprint; //所有待打印的数据容器
if(pRoot == nullptr)
return Vprint;
stack<TreeNode*> s1, s2; //栈里面存放的是指向该节点的指针
vector<int> Vrow; //行容器,存放的是该节点的数据域
s1.push(pRoot);
while(!s1.empty() || !s2.empty()){
//1.从s1出发,弹出s1栈顶元素,弹出前将其子节点(从左向右)压入s2
while(!s1.empty()){
TreeNode* pNode = s1.top();
Vrow.push_back(pNode->val); //出栈前将栈顶元素放进Vrow容器中
if(pNode->left)
s2.push(pNode->left);
if(pNode->right)
s2.push(pNode->right);
s1.pop(); //左右子节点压入到栈s2后,s1栈顶元素出栈
}
if(!Vrow.empty()){
Vprint.push_back(Vrow);
Vrow.clear(); //清空Vrow中元素
}
//2.从s2出发,弹出s2栈顶元素,弹出前将其子节点(从右向左)压入s1
while(!s2.empty()){
TreeNode* pNode = s2.top();
Vrow.push_back(pNode->val);
if(pNode->right)
s1.push(pNode->right);
if(pNode->left)
s1.push(pNode->left);
s2.pop();
}
if(!Vrow.empty()){
Vprint.push_back(Vrow);
Vrow.clear();
}
}
return Vprint;
}
};