zoukankan      html  css  js  c++  java
  • L2-006 树的遍历 (层序遍历)

      根据访问根节点与左右子树的先后顺序,二叉树一般有三种遍历方式:先序遍历、中序遍历和后序遍历。

      只要给定中序遍历序列与先序或后序中的一种,可以还原二叉树结构。学习数据结构课程时,一直都只会手动构建还原二叉树。今天试着解决了该问题,记录一下成果。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    const int maxn = 50;
    int preorder[maxn], inorder[maxn];
    
    struct Node{
        int l, r;
    }nodes[maxn];
    
    int build(int pl, int pr, int il, int ir)
    { // 以[pl,pr] [il, ir]建立二叉树,返回根节点
    
        if(pl>pr) return 0;
        if(il>ir) return 0;
        int root = preorder[pl];
    
        // 在中序遍历中找到跟节点,分成左右子树递归建树
        int pos = il;
        while(inorder[pos]!=root) pos++;
        int _left = pos - il;
    
        nodes[root].l  = build(pl+1, pl+_left, il, pos-1);
        nodes[root].r  = build(pl+_left+1, pr, pos+1, ir);
    
        return root;
    }
    
    void PreReverse(int rt)
    { // 先序遍历
        cout<<rt<<' ';
        
        if(nodes[rt].l) PreReverse(nodes[rt].l);
    
        if(nodes[rt].r) PreReverse(nodes[rt].r);
    }
    
    void PostReverse(int rt)
    { // 后序遍历
        if(nodes[rt].l) PostReverse(nodes[rt].l);
    
        if(nodes[rt].r) PostReverse(nodes[rt].r);
    
        cout<<rt<<' ';
    }
    
    int main()
    {
        int N; cin>>N;
    
        for(int i=0;i<N;i++)
            cin>>preorder[i];
        for(int i=0;i<N;i++)
            cin>>inorder[i];
    
        int rt = build(0, N-1, 0, N-1);
    
        PreReverse(rt);
        PostReverse(rt);
        
    /*
    7
    3 5 7 6 1 8 2
    7 5 1 6 3 8 2
    
    后序遍历结果:
    7 1 6 5 2 8 3
    */
    
        return 0;
    }

      稍加修改应该可以解决此题(L2-006 树的遍历),最后输出层序遍历的序列,即BFS。(开始理解错了,对结果没影响)

      AC代码如下:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    
    const int maxn = 50;
    int postorder[maxn], inorder[maxn];
    
    struct Node{
        int l, r;
    }nodes[maxn];
    
    int build(int pl, int pr, int il, int ir)
    { // 以[pl,pr] [il, ir]建立二叉树,返回根节点
    
        if(pl>pr) return 0;
        if(il>ir) return 0;
        int root = postorder[pr];
    
        // 在中序遍历中找到跟节点,分成左右子树递归建树
        int pos = il;
        while(inorder[pos]!=root) pos++;
        int _left = pos - il;
    
        nodes[root].l  = build(pl, pl+_left-1, il, pos-1);
        nodes[root].r  = build(pl+_left, pr-1, pos+1, ir);
    
        return root;
    }
    
    int main()
    {
        int N; cin>>N;
    
        for(int i=0;i<N;i++)
            cin>>postorder[i];
        for(int i=0;i<N;i++)
            cin>>inorder[i];
    
        int rt = build(0, N-1, 0, N-1);
        cout<<rt;
    
        queue<int> q;
        if(nodes[rt].l)
            q.push(nodes[rt].l);
        if(nodes[rt].r)
            q.push(nodes[rt].r);
    
        while(!q.empty())
        {
            int k = q.front(); q.pop();
            cout<<' '<<k;
            if(nodes[k].l)
                q.push(nodes[k].l);
            if(nodes[k].r)
                q.push(nodes[k].r);
        }
    
        return 0;
    }

      // 2019.3.21 更新

      今天做题发现层序遍历并不是单纯的BFS,在leetcode上碰到这样一个需要严格按照树的层次输出的题:

      二叉树结构:  输出结果:

    想了半天并没有想到标记每一个层次的办法,搜索解答才恍然大悟,代码非常简单!

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<vector<int>> levelOrder(TreeNode* root) {
            queue<TreeNode*> q;
            q.push(root);
    
            vector<vector<int> > ans;
            if(root==NULL) return ans;
            
            while(!q.empty())
            {
                vector<int> tmp;  // 保存每一层的遍历结果
                int size = q.size();
                while(size--)
                {
                    TreeNode *now = q.front();  q.pop();
                    tmp.push_back(now->val);
                    
                    if(now->left) q.push(now->left);
                    if(now->right) q.push(now->right);
                    
                }
                ans.push_back(tmp);  
            }
            return ans;
        }
    };    
  • 相关阅读:
    分不清npm cnpm npx nvm ?
    gulp 中对于css文件的压缩合并出现的unable to minify JavaScript问题
    JS实现选项卡和JQ实现选项卡
    前端性能的优化
    JS中事件绑定的方式以及事件监听和事件的委托
    简易轮播图和无缝轮播图的实现
    ES6中对象的扩展以及新增方法
    javascript的基本介绍和发展
    this浅谈
    浅谈DOM的概念和作用
  • 原文地址:https://www.cnblogs.com/izcat/p/10519887.html
Copyright © 2011-2022 走看看