题目一
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
思路
实际上这在考树的遍历算法,二叉树的前中后序遍历的非递归版本都会用到stack,具体代码看笔记。
从左到右,只需在打印某个节点时,用队列将节点的左右节点加入队列尾部,然后不断打印队列头,打印完后删除
直到队列为空
不管是按广度优先,遍历有向图还是一棵树,都会用到队列!
class Solution { public: vector<int> PrintFromTopToBottom(TreeNode* root) { vector<int> res; if(root == nullptr) return res; queue<TreeNode*> q; q.push(root); while(!q.empty()){ res.push_back(q.front()->val); if(q.front()->left) q.push(q.front()->left); if(q.front()->right) q.push(q.front()->right); q.pop(); } return res; } };
题目二
分行从上到下打印二叉树,如
输出
8
6 10
5 7 9 11
思路
有题一铺垫,不难想到,还是用队列存储下一行,只需记录下一行有多少节点
然后再打印时,如果该行节点数已经打印完,则换行
class Solution { public: vector<vector<int>> PrintFromTopToBottom(TreeNode* root) { vector<vector<int>> res; if(root == nullptr) return res; queue<TreeNode*> q; q.push(root); int nextLevel = 0, toBePrint = 1; while(!q.empty()){
vector<int> data; data.push_back(q.front()->val); if(q.front()->left) { q.push(q.front()->left); nextLevel++; } if(q.front()->right) { q.push(q.front()->right); nextLevel++; } q.pop(); toBePrint--; if (toBePrint == 0) { res.push_back(data); // 这一句是伪代码,意会即可 toBePrint = nextLevel; nextLevel = 0; } } return res; } };
题目三
按之字形打印二叉树,如
输出:
1
3 2
4 5 6 7
15 14 13 12 11 10 9 8
思路
自然会想到用栈
当打印奇数层时,先将左节点压入,再将右节点压入
当打印偶数层时,先将右节点压入,再将左节点压入
而且必须用两个栈,因为栈不向队列,它是单向的。
打印1时
打印3 2时
打印 4 5 6 7时
class Solution { public: vector<vector<int> > Print(TreeNode* pRoot) { vector<vector<int>> res; if (!pRoot) return res; stack<TreeNode*> s1, s2; s1.push(pRoot); TreeNode* temp; while (!s1.empty() || !s2.empty()) { vector<int> data; if (!s1.empty()) { while(!s1.empty()) { temp = s1.top(); s1.pop(); data.push_back(temp->val); if (temp->left) s2.push(temp->left); if (temp->right) s2.push(temp->right); } res.push_back(data); } else if (!s2.empty()) { while(!s2.empty()) { temp = s2.top(); s2.pop(); data.push_back(temp->val); if (temp->right) s1.push(temp->right); if (temp->left) s1.push(temp->left); } res.push_back(data); } } return res; } };