OJ练习23——T102 Binary Tree Level Order Traversal

层次遍历二叉树,结果分行列出:

[
  [3],
  [9,20],
  [15,7]
]

【思路】

层次遍历要用队列,还要有记录每层节点数的数组。

记录层数是难点,要用每个节点来推算其下一层,看到remlostime的做法是自定义struct,带一个level信息,必须这样吗??

【盲点】

c++栈和队列

头文件:#include<stack>  #include<queue>

定义:

定义栈如下:stack<int> stk;

定义队列如下:queue<int> q;

操作:

s.empty()               如果栈为空返回true,否则返回false
s.size()                返回栈中元素的个数
s.pop()                 删除栈顶元素但不返回其值
s.top()                 返回栈顶的元素,但不删除该元素
s.push()                在栈顶压入新元素
q.empty()               如果队列为空返回true,否则返回false
q.size()                返回队列中元素的个数
q.pop()                 删除队列首元素但不返回其值
q.front()               返回队首元素的值,但不删除该元素
q.push()                在队尾压入新元素
q.back()                返回队列尾元素的值,但不删除该元素

【my code】(part,待完善)

private:
    vector<vector<int> > ret;
public:
    vector<vector<int> > levelOrder(TreeNode *root) {
        queue<TreeNode*> q;
        TreeNode *p=root, *r;
        vector<int> level;
        int nnum=0;
        if(p)
        {
            q.push(p);
            level.push_back(1);
            while(!q.empty())
            {
                level.push_back(0);
                nnum++;
                r=q.front();
                //cout<<'['<<q.front()<<',';
                if(r->left){
                    q.push(r->left);
                    level[nnum]++;
                }
                if(r->right){
                    q.push(r->right);
                    level[nnum]++;
                }
                q.pop();
            }
        }
    }

【评价】

用这个思路比较繁琐,先暂停一下,用个简单的。

【other code】

class Solution {
private:
    vector<vector<int> > ret;
public:
    void solve(int dep, TreeNode *root)
    {
        if(root==NULL)
            return;
        if(ret.size()>dep)
        {
            ret[dep].push_back(root->val);
        }
        else{
            vector<int> a;
            a.push_back(root->val);
            ret.push_back(a);
        }
        solve(dep+1, root->left);
        solve(dep+1, root->right);
    }
    vector<vector<int> > levelOrder(TreeNode *root) {
        ret.clear();
        solve(0, root);
        return ret;
    }
};

【评价】

写的太好了。

if(ret.size()>dep)就是说如果总层数(即ret.size())大于当前所在层数,就在当前层数增加节点值。

不需要用队列和level结构。

这就是所谓的,DFS深度优先遍历。上面我的思路是广度优先,也就是层次遍历的基本思路。

长见识,层次遍历也是可以用深度优先遍历实现的。

记住这个代码!

【后记】

但是效率不高,在这里

【4月23日补充】

看到一个BFS高效简短,不需要在结构中添加level的做法:http://www.cnblogs.com/Azhu/p/4132676.html

【other code2】

vector<vector<int> > levelOrderBottom(TreeNode *root) {
        vector<vector<int> >ret;
        if(root==NULL)  return ret;
        vector<int> line;
        queue<TreeNode *> que;
        TreeNode * curNode;
        que.push(root);
        que.push(NULL);
        while(que.size()>1){
            curNode=que.front();
            que.pop();
            if(curNode==NULL){
                ret.push_back(line);
                line.clear();
                que.push(NULL);
                continue;
            }
            line.push_back(curNode->val);
            if(curNode->left!=NULL) que.push(curNode->left);
            if(curNode->right!=NULL)    que.push(curNode->right);

        }
        ret.push_back(line);
        //reverse(ret.begin(),ret.end());//这是另一道题的解法
        return ret;
    }

【解析】

这里不需要用level,而是在队列中每一行的最后一个加push(NULL)作为标记,pop时遇到NULL说明一行结束,把前面输出的line push_back到ret后面,

再把line清零。思路十分清晰。记住这段!

用while代替递归,效率要高很多。

【意外收获】

在上面链接中的BFS代码中,有这样一段:

int main()
{
    Solution sol;
    TreeNode node1(1);
    TreeNode node2(2);
    TreeNode node3(3);
    TreeNode node4(4);
    node1.right=&node2;
    node2.left =&node3;
    node2.right =&node4;

    vector<vector<int> >ret =sol.levelOrderBottom(&node1);
    for(int i=0;i<ret.size();i++){
        copy(ret[i].begin(),ret[i].end(),ostream_iterator<int>(cout," "));
        cout<<endl;
    }
    system("pause");

    return 0;
}

查了一下这句话的用法:

copy(ret[i].begin(),ret[i].end(),ostream_iterator<int>(cout," "));

原来是输入输出的经典句子:

copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(ivec));
//将输入赋给ivec,如果不是int则终结 //下句为将ivec内容输出屏幕 copy(ivec.begin(),ivec.end(),ostream_iterator<int>(cout," "));//以 间隔

 需要include<iterator>。

详见:http://blog.csdn.net/fdl19881/article/details/6685744

原文地址:https://www.cnblogs.com/ketchups-notes/p/4443767.html