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;
    }
};    

 

posted @ 2019-03-12 21:45  izcat  阅读(639)  评论(0编辑  收藏  举报