leetcode上对应习题序号
102,103,107,119
make_pair<Treenode *,int>存储当前结点和结点所在的层数
层序遍历,顾名思义,就是每次打印一行,这一行代表当前树的一层,如果按照普通要求,就是把每个节点值按照层序从上到下从左到右依次输出,那么为什么会选择队列来保存结点呢
头节点放进队列中,队列不为空,然后对队列中的元素依次进行操作
rel.push——back(root)
while (!rel.empty())
BinaryTree* front = rel.front();
然后对这个front操作,再把该节点的左右结点放进队列中
其中队列直接保存的是二叉树结点指针 queue<BinaryTree*> rel
而对于希望以特殊方式打印出来的,采取如下方法
改变在于队列存储的是一对元素,分别是树节点指针,和该节点对应所在层次level,每次对队列头操作pop和赋值的时候,都把它的左右节点都放入队列中
先进先出,后今后出。 Treenode *node=q.front().first;
int level=q.front().second;
当然还得判断res数组当前的层次是否等于队列pop元素的,如果res的size==level,说明这个level的值还没存进去
总之,是这样一个操作过程
首先,结果数组res--第一个值对应level,这一行存的就是这层的树节点值
队列q--pair值,树节点指针,和该节点的层
把二叉树头节点存进去,并把该节点赋值给res,注意在这个过程中,res的数组大小要扩展
每次再队列中pop一个元素,都要把该节点的左右结点都放进去,
其实我觉得可以先把树节点信息全部放进队列中,然后再把队列元素的pop()出来,给res
struct Treenode
{
int val;
Treenode *left;
Treenode *right;
}
vector<vector<int> >P(Treenode *root)
{
Queue<pair<Treenode*,int> >q;
q.push_back(make_pair(root,0));
vector<vector<int> >res;
while(!q.empty())
{
Treenode *node=q.front().first;
int level=q.front().second;
q.pop();
if(leve==res.size())
res.push_back(vector<int> )
res[level].push_back(node->val);
return res;
node是循环的关键
if(node->left)
q.push_back(make_pair(h->left,level+1));
if(node->right)
q.push_back(make_pair(h->right,level+1));
}
还有一种方法:
循环里边是当前树的层次里边的结点,因为pop之后,每一次存储的是当前层次的结点
1 class Solution
2 {
3 public:
4 vector<vector<int> > levelOrderBottom(TreeNode *root)
5 {
6 vector<vector<int> > vvi;
7
8 if(NULL == root)
9 return vvi;
10
11 queue<TreeNode *> q;
12 q.push(root);
13 while(!q.empty())
14
{
15 vector<int> vi;
16 for(int i = 0, n = q.size(); i < n; ++ i)
17
{
18 TreeNode *temp = q.front();
19 q.pop();
20 if(temp -> left != NULL)
21 q.push(temp -> left);
22 if(temp -> right != NULL)
23 q.push(temp -> right);
24 vi.push_back(temp -> val);
25 }26
vvi.push_back(vi);
27 }
28 reverse(vvi.begin(), vvi.end());
29 return vvi;
30 }
31 };