樹的遍歷方式例題


。。。天梯模擬賽沒寫出樹的遍歷。。。補幾道類似的題

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM