zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    生产环境常见的几种JVM异常
    JVM垃圾回收时如何确定垃圾?是否知道什么是GCRoots?
    你平时工作用过的JVM常用基本配置参数有哪些?
    java X参数
    JUC之CAS
    JUC之List集合
    JUC之lock
    JUC之volatile
    BZOJ2132: 圈地计划
    BZOJ3991: [SDOI2015]寻宝游戏
  • 原文地址:https://www.cnblogs.com/ketchups-notes/p/4443767.html
Copyright © 2011-2022 走看看