• 【历年真题】严格二叉树已知前序和后序还原这棵树


    一颗二叉树,其左右子树都空,或都不空,则为“严格二叉树”,用先序遍历
    和后序遍历能确定一颗严格二叉树,二叉树的前序序列为 ABDECFHIGJLKMN,后序序列为 DEBHIFLJMNKGCA.
    然后输出其中序遍历

    【题解】

    主要就是根据这个二叉树的特点写个递归就好。 因为如果有左子树一定有右子树。 所以先序遍历当前节点的下一个节点一定是左子树的根节点。 那么我们只要在后序遍历中找到这个左子树的根节点就好了。 然后,在后序遍历中这个左子树的根节点的左边的点肯定就都是它的子树里的节点了。 那么它后面的点是什么呢?肯定就是当前节点的右子树的后序遍历了(除了最后一个节点即根节点本身外) 然后递归,找到每个节点的左右儿子节点就行

    【代码】

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    const int N = 100;
    
    int l[N+10],r[N+10],root,cur;
    char dic[N+10];
    
    //前序后序
    string s1,s2;
    int len1,len2;
    
    //返回和前序中l1..r1后序中l2..r2对应的树的根节点
    int doit(int l1,int r1,int l2,int r2){
        if (l1>r1) return -1;
        char key = s1[l1];
        int now = ++cur;
        dic[now] = key;
        if (l1+1>r1) return now;//如果是叶子节点,就直接返回这个节点
        //不是叶子节点,那么一定有左子树和右子树
        char keyl = s1[l1+1];
        int j;
        for (int i = l2;i <= r2;i++)//在后序中找到key的左子树的根节点
            if (s2[i]==keyl){
                j = i;
                break;
            }
        //则l2..j这一段是key的左子树对应的后序遍历
        int len = j-l2+1;
        l[now] = doit(l1+1,l1+1+len-1,l2,j);
        //而j+1..r2-1这一段是key的右子树对应的后序遍历
        r[now] = doit(l1+1+len,r1,j+1,r2-1);
        return now;
    }
    
    void dfs(int x){
        if (x<=0) return;
        dfs(l[x]);
        printf("%c",dic[x]);
        dfs(r[x]);
    }
    
    int main(){
        //freopen("D:\rush.txt","r",stdin);
        cin >> s1 >> s2;
        len1 = s1.size();len2 = s2.size();
        root = doit(0,len1-1,0,len2-1);
        dfs(root);//输出其中序遍历
        return 0;
    }
    
    
  • 相关阅读:
    CentOS7 防火墙firewalld详细操作
    bootstrap-datetimepicker 滚动错位问题
    Contos更换python版本
    centos7.3下使用yum 安装pip
    备注
    jenkins与SVN 问题记录
    kafka配置
    Jenkins 与github配置
    nginx File not found 错误
    nginx 总结
  • 原文地址:https://www.cnblogs.com/AWCXV/p/11625611.html
Copyright © 2020-2023  润新知