• 如何求先序排列和后序排列——hihocoder1049+洛谷1030+HDU1710+POJ2255+UVA548【二叉树递归搜索】


    【已知先序、中序求后序排列】——字符串类型
    #1049 : 后序遍历

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB
    描述
    小Ho在这一周遇到的问题便是:给出一棵二叉树的前序和中序遍历的结果,还原这棵二叉树并输出其后序遍历的结果。
    提示:分而治之——化大为小,化小为无
    输入
    每个测试点(输入文件)有且仅有一组测试数据。
    每组测试数据的第一行为一个由大写英文字母组成的字符串,表示该二叉树的前序遍历的结果。
    每组测试数据的第二行为一个由大写英文字母组成的字符串,表示该二叉树的中序遍历的结果。
    对于100%的数据,满足二叉树的节点数小于等于26。
    输出
    对于每组测试数据,输出一个由大写英文字母组成的字符串,表示还原出的二叉树的后序遍历的结果。
    样例输入
    AB
    BA
    样例输出
    BA
    

    【分析】:在注释里面。

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e3 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    string a,b;
    string dfs(int l1,int l2,int len)//l1前序起点、l2中序起点、len是树的总长
    {
        int i;
        if(len<=0) return "";
        for(i=l2;i<l2+len;i++)
        {
            if(b[i]==a[l1])
                break;//用i记录当前根节点
        }
        int cnt=i-l2;//左子树遍历的长度
        string a1 = dfs(l1+1,l2,cnt);//递归左子树,左子树先序遍历起始点为l1+1,左子树中序遍历起始点始终为l2
        string a2 = dfs(l1+cnt+1,i+1,len-cnt-1);//递归右子树,右子树先序遍历起始点在左子树右侧为l1+cnt+1,右子树中序遍历始终在根节点i右侧为i+1
        return a1+a2+a[l1];//由于是后序遍历 层数最低的根节点放置末尾
    }
    
    int main()
    {
        while(cin>>a>>b)
        {
           cout<< dfs(0,0,a.length()) << endl;
        }
    }
    
    

    (已知前序、中序求后序)[http://acm.hdu.edu.cn/showproblem.php?pid=1710]——【int数组类型】

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e3 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int pre[maxn],mid[maxn],post[maxn],k=0;
    //给一棵树的前序,中序输出后序
    /*
    先序遍历的第一个节点一定是这棵树上的根节点,
    那么在中序遍历里找到根节点,
    中序数组根节点左边的元素全在左子树,
    右边的元素在右子树,一直划分到叶子节点为止。
    */
    void dfs(int l1,int r1,int l2,int r2)
    {
        if(l1>r1 || l2>r2) return ;
        int o = pre[l1], pos;
        for(int i=l2; ;i++)
        {
            if(mid[i] == o)
            {
                pos = i;
                break;
            }
        }
        int cnt = pos - l2;//左子树大小
        dfs(l1+1,l1+cnt,  l2,pos-1);    //左子树->前+中
        dfs(l1+cnt+1,r1,  pos+1,r2);  //右子树->前+中
        post[k++]=o;
    }
    
    int n;
    int main()
    {
        while(~scanf("%d",&n))
        {
            k=0;
            for(int i=1;i<=n;i++)
                scanf("%d",&pre[i]);
            for(int i=1;i<=n;i++)
                scanf("%d",&mid[i]);
            dfs(1,n,1,n);
        for(int i=0;i<k;i++)
            printf("%d%c",post[i],i==k-1?'
    ':' ');
        }
    }
    /*
    9
    1 2 4 7 3 5 8 9 6
    4 7 2 1 8 5 9 3 6
    7 4 2 8 9 5 6 3 1
    */
    
    

    洛谷:
    【已知中序、后序求先序】——字符串类型:
    题目描述
    给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度 le 8≤8 )。

    输入输出格式
    输入格式:
    22 行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。

    输出格式:
    11 行,表示一棵二叉树的先序。

    输入输出样例
    输入样例#1:
    BADC
    BDCA
    输出样例#1:
    ABCD

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e3 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    char pre[maxn],mid[maxn],post[maxn];
    int k=0;
    vector<char> v;
    //给一棵树的中序、后序输出 求先序排列[int]
    void dfs(int l1,int r1,int l2,int r2)
    {
        if(l1>r1) return;
        int o = post[r2], pos;
        v.push_back(o);
        for(int i=l1; ;i++)
        {
            if(mid[i] == o)
            {
                pos = i;
                break;
            }
        }
        int cnt = pos - l1;//左子树大小
        dfs(l1,pos-1, l2,l2+cnt-1);//左子树->中+后
        dfs(pos+1,r1, l2+cnt,r2-1);//右子树->中+后
        //pre[k++]=o;
    }
    
    int n;
    int main()
    {
        while(~scanf("%s%s",mid,post))
        {
            v.clear();
            k=0;
            int n = strlen(mid);
            dfs(0,n-1,0,n-1);
            for(int i=0;i<v.size();i++)
            {
                printf("%c",v[i]);
            }
            cout<<endl;
        }
    }
    /*
    4
    2 1 4 3
    2 4 3 1
    */
    
    

    【已知中序、后序求先序】——int类型

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e3 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int pre[maxn],mid[maxn],post[maxn],k=0;
    vector<int> v;
    //给一棵树的中序、后序输出 求先序排列[int]
    void dfs(int l1,int r1,int l2,int r2)
    {
        if(l1>r1) return;
        int o = post[r2], pos;
        v.push_back(o);
        for(int i=l1; ;i++)
        {
            if(mid[i] == o)
            {
                pos = i;
                break;
            }
        }
        int cnt = pos - l1;//左子树大小
        dfs(l1,pos-1, l2,l2+cnt-1);//左子树->中+后
        dfs(pos+1,r1, l2+cnt,r2-1);//右子树->中+后
        //pre[k++]=o;
    }
    
    int n;
    int main()
    {
        while(~scanf("%d",&n))
        {
            v.clear();
            k=0;
            for(int i=1;i<=n;i++)
                scanf("%d",&mid[i]);
            for(int i=1;i<=n;i++)
                scanf("%d",&post[i]);
            dfs(1,n,1,n);
            for(int i=0;i<v.size();i++)
            {
                if(i!=v.size()-1)
                printf("%d ",v[i]);
                else printf("%d
    ",v[i]);
            }
        }
    }
    /*
    4
    2 1 4 3
    2 4 3 1
    */
    
    
  • 相关阅读:
    使用jetty部署配置solr服务
    solr 与 MySQL(二)
    学习solr(一)
    FormData 上传文件
    node.js cannot find module 'mysql'
    select2 ajax 无法选中
    jenkins持续集成文件冲突的问题
    Inno Setup 实现每次jenkins自动构建时版本号自动+1
    jenkins 配置slave节点(win10系统)
    Jenkins+Gradle实现android开发持续集成和打包
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9380070.html
Copyright © 2020-2023  润新知