树的遍历方式例题

。。。天梯模拟赛没写出树的遍历。。。补几道类似的题

 

L2-004 这是二叉搜索树吗?

链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805070971912192

思路:先核对这串序列是否符合先序遍历,如果不符合再核对下是否符合镜像后的,因为题目要求给出树的后序遍历,所以每次核对的时候都按照后序遍历存点。

实现代码:

#include<bits/stdc++.h>
using namespace std;

vector<int>v;
int a[1010],is;

void dfs(int l,int r){
    if(l > r) return ;
    int tr = l+1;
    int tl = r;
    if(!is){
        while(tr <= r&&a[tr] < a[l]) tr++;
        while(tl > l&&a[tl] >= a[l]) tl--;
    }
    else{
        while(tr <= r&&a[tr] >= a[l]) tr++;
        while(tl > l&&a[tl] < a[l]) tl--;
    }
    if(tr - tl != 1) return ;
    dfs(l+1,tl);
    dfs(tr,r);
    v.push_back(a[l]);
}

int main()
{
    int n;
    cin>>n;
    for(int i = 0;i < n;i ++){
        cin>>a[i];
    }
    dfs(0,n-1);
    if(v.size()!=n){
        is = 1;
        v.clear();
        dfs(0,n-1);
    }
    if(v.size() != n) cout<<"NO"<<endl;
    else{
        cout<<"YES"<<endl;
        for(int i = 0;i < n;i ++){
            cout<<v[i];
            if(i != n-1) cout<<" ";
        }
        cout<<endl;
    }
}

 

L2-006 树的遍历 

链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456

思路:后序遍历最后一个点是根,我们得到这个根,在中序遍历上找到这个根的位置p,可以以此推出左子树的大小为p-l1,这样两个序的左右子树的区间都可以被找到,保存下当前根节点左右子节点的值,然后用bfs跑出层次遍历的序列。

 

实现代码:

#include<bits/stdc++.h>
using namespace std;
const int M = 1e3+10;
int post_order[M],in_order[M],lch[M],rch[M],n;
int build(int l1,int r1,int l2,int r2){
    if(l1 > r1) return 0;
    int rt = post_order[r2];
    int p = l1;
    while(in_order[p]!=rt) p++;
    int cnt = p-l1;
    lch[rt] = build(l1,p-1,l2,l2+cnt-1);
    rch[rt] = build(p+1,r1,l2+cnt,r2-1);
    return rt;
}

void bfs()
{
    queue<int>q;
    vector<int>v;
    q.push(build(0,n-1,0,n-1));
    while(!q.empty()){
        int cur = q.front();
        q.pop();
        v.push_back(cur);
        if(lch[cur]) q.push(lch[cur]);
        if(rch[cur]) q.push(rch[cur]);
    }
    for(int i = 0;i < v.size();i ++){
        cout<<v[i];
        if(i != v.size()-1) cout<<" ";
    }
    cout<<endl;
}

int main()
{
    cin>>n;
    for(int i = 0;i < n;i ++)
        cin>>post_order[i];
    for(int i = 0;i < n;i ++)
        cin>>in_order[i];
    bfs();
    return 0;
}

 

L2-011 玩转二叉树 

链接: https://pintia.cn/problem-sets/994805046380707840/problems/994805065406070784

思路; 之前比赛没写来,写完上面两道题后就秒a了。。。

跟前一道基本一样,就是后序换成了前序,这个知道了原理就很好处理了就是根的在第一个罢了。后面镜像操作,我们存左右儿子的时候直接交换存就好了。

实现代码;

#include<bits/stdc++.h>
using namespace std;
const int M = 1e3 + 10;
int pre[M],mid[M],lch[M],rch[M],n;
int build(int l1,int r1,int l2,int r2){
     if(l1 > r1) return 0;
     int rt = pre[l2];
     int p = l1;
     while(mid[p] != rt) p++;
     int cnt = p-l1;
     rch[rt] = build(l1,p-1,l2+1,l2+cnt);
     lch[rt] = build(p+1,r1,l2+cnt+1,r2);
     return rt;
}

void bfs( ){
    vector<int>v;
    queue<int>q;
    q.push(build(0,n-1,0,n-1));
    while(!q.empty()){
        int cur = q.front();
        q.pop();
        if(lch[cur]) q.push(lch[cur]);
        if(rch[cur]) q.push(rch[cur]);
        v.push_back(cur);
    }
    for(int i = 0;i < v.size();i ++){
        cout<<v[i];
        if(i != v.size()-1) cout<<" ";
    }
    cout<<endl;
}

int main()
{
    cin>>n;
    for(int i = 0;i < n;i ++){
        cin>>mid[i];
    }
    for(int i = 0;i < n;i ++){
        cin>>pre[i];
    }
    bfs();
    return 0;
}

 

posted @ 2019-03-27 17:08  冥想选手  阅读(1030)  评论(0编辑  收藏  举报