层序遍历(宽度优先遍历BFS)(从上到下):使用双端队列deque
思路:
层序遍历二叉树是典型的广度优先搜索BFS的应用,但是这里稍微复杂一点的是,我们要把各个层的数分开,存到一个二维向量里面,大体思路还是基本相同的,建立一个queue,然后先把根节点放进去,这时候找根节点的左右两个子节点,这时候去掉根节点,此时queue里的元素就是下一层的所有节点,用一个for循环遍历它们,然后存到一个一维向量里,遍历完之后再把这个一维向量存到二维向量里,以此类推,可以完成层序遍历。代码如下:
- /**
- * Definition of TreeNode:
- * class TreeNode {
- * public:
- * int val;
- * TreeNode *left, *right;
- * TreeNode(int val) {
- * this->val = val;
- * this->left = this->right = NULL;
- * }
- * }
- */
- class Solution {
- public:
- /**
- * @param root: A Tree
- * @return: Level order a list of lists of integer
- */
- vector<vector<int>> levelOrder(TreeNode * root) {
- // write your code here
- vector<vector<int> >st;
- deque<TreeNode*>node;//双端队列
- if (root == NULL)
- return st;
- node.push_back(root);
- int len;
- while(!node.empty())
- {
- vector<int>temp;
- len=node.size();//很重要这一步,不能用empty()测试node是否为空
- while(len--)
- {
- TreeNode*pt=node.front();
- temp.push_back(pt->val);
- node.pop_front();
- if(pt->left)
- node.push_back(pt->left);
- if(pt->right)
- node.push_back(pt->right);
- }
- st.push_back(temp);
- }
- return st;
- }
- };
从底部层序遍历其实还是从顶部开始遍历,只不过最后存储的方式有所改变
锯齿形遍历(宽度优先遍历)(使用两个栈)
- /**
- * Definition of TreeNode:
- * class TreeNode {
- * public:
- * int val;
- * TreeNode *left, *right;
- * TreeNode(int val) {
- * this->val = val;
- * this->left = this->right = NULL;
- * }
- * }
- */
- class Solution {
- public:
- /**
- * @param root: A tree
- * @return: buttom-up level order a list of lists of integer
- */
- vector<vector<int>> levelOrderBottom(TreeNode * root) {
- // write your code here
- vector<vector<int> >st;
- deque<TreeNode*>node;//双端队列
- if (root == NULL)
- return st;
- node.push_back(root);
- int len;
- while(!node.empty())
- {
- vector<int>temp;
- len=node.size();//很重要这一步,不能用empty()测试node是否为空
- while(len--)
- {
- TreeNode*pt=node.front();
- temp.push_back(pt->val);
- node.pop_front();
- if(pt->left)
- node.push_back(pt->left);
- if(pt->right)
- node.push_back(pt->right);
- }
- st.insert(st.begin(),temp);
- }
- return st;
- }
- };
分析:第一层从左到右遍历、第二层从右到左遍历,第三层从左到右遍历.......
根据其特点我们用到栈的后进先出的特点,这道题我们维护两个栈,相邻两行分别存到两个栈中,进栈的顺序也不相同,一个栈是先进左子结点然后右子节点,另一个栈是先进右子节点然后左子结点,这样出栈的顺序就是我们想要的之字形了,代码如下:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int> > zigzagLevelOrder(TreeNode *root) {
vector<vector<int> >res;
if (!root) return res;
stack<TreeNode*> s1;
stack<TreeNode*> s2;
s1.push(root);
vector<int> out;
while (!s1.empty() || !s2.empty()) {
while (!s1.empty()) {
TreeNode *cur = s1.top();
s1.pop();
out.push_back(cur->val);
if (cur->left) s2.push(cur->left);
if (cur->right) s2.push(cur->right);
}
if (!out.empty()) res.push_back(out);
out.clear();
while (!s2.empty()) {
TreeNode *cur = s2.top();
s2.pop();
out.push_back(cur->val);
if (cur->right) s1.push(cur->right);
if (cur->left) s1.push(cur->left);
}
if (!out.empty()) res.push_back(out);
out.clear();
}
return res;
}
};
迭代法(使用队列实现)
层序遍历的思路,但是对偶数层的temp使用reverse函数
- /**
- * Definition of TreeNode:
- * class TreeNode {
- * public:
- * int val;
- * TreeNode *left, *right;
- * TreeNode(int val) {
- * this->val = val;
- * this->left = this->right = NULL;
- * }
- * }
- */
- class Solution {
- public:
- /**
- * @param root: A Tree
- * @return: A list of lists of integer include the zigzag level order traversal of its nodes' values.
- */
- vector<vector<int>> zigzagLevelOrder(TreeNode * root) {
- // write your code here
- vector<vector<int> >st;
- deque<TreeNode*>node;
- if (root == NULL)
- return st;
- node.push_back(root);
- bool count=true;
- vector<int>temp;
- int len;
- while(!node.empty())
- {
- len=node.size();
- while(len--)
- {
- TreeNode*pt=node.front();
- temp.push_back(pt->val);
- node.pop_front();
- if(pt->left)
- node.push_back(pt->left);
- if(pt->right)
- node.push_back(pt->right);
- }
- if(!count)
- reverse(temp.begin(),temp.end());
- //对temp使用reverse函数,一种比较简便的方法
- count=!count;
- st.push_back(temp);
- temp.clear();
- }
- return st;
- }
- };