【C++】根据二叉树的前序遍历和中序遍历重建二叉树并输出后续遍历

复制代码
/*
现在有一个问题,已知二叉树的前序遍历和中序遍历:
PreOrder:GDAFEMHZ
InOrder:ADEFGHMZ
我们如何还原这颗二叉树,并求出他的后序遍历

我们基于一个事实:中序遍历一定是 { 左子树中的节点集合 },root,{ 右子树中的节点集合 },前序遍历的作用就是找到每颗子树的root位置。

算法1
输入:前序遍历,中序遍历
1、寻找树的root,前序遍历的第一节点G就是root。
2、观察前序遍历GDAFEMHZ,知道了G是root,剩下的节点必然在root的左或右子树中的节点。
3、观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树中的节点,G右侧的HMZ必然是root的右子树中的节点,root不在中序遍历的末尾或开始就说明根节点的两颗子树都不为空。
4、观察左子树ADEF,按照前序遍历的顺序来排序为DAFE,因此左子树的根节点为D,并且A是左子树的左子树中的节点,EF是左子树的右子树中的节点。
5、同样的道理,观察右子树节点HMZ,前序为MHZ,因此右子树的根节点为M,左子节点H,右子节点Z。

观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了:

PreOrder:GDAFEMHZ
InOrder:ADEFGHMZ
从而得到PostOrder:       
AEFDHZMG
*/


#include<iostream>
#include<cstring>
using namespace std;
const int M=1024;
char pr[M];
char in[M];

struct node
{
    char data;
    node *l;
    node *r;
};
/*
void build(node * & t,int prl,int prr,int inl,int inr)
{
    char m=pr[prl];
    //printf("%c\n",m);
    if(prl>prr||inl>inr)
    {
        t=NULL;
        return ;
    }
    int i1=0;// -> middle num in the pr
    int i2=0;// -> middle num in the in
    while(in[i2]!=m)
        i2++;
    i1=i2;
    t=new node();
    t->data=m;
    
    if(prl==prr||inl==inr)
    {
        t->l=NULL;
        t->r=NULL;
        return ;
    }
    else
    {
        build(t->l,prl+1,i1,inl,i2-1);//go build left part
        build(t->r,i1+1,prr,i2+1,inr);//go build right part
    }
}
*/
void create(node * &t, int preL, int preR, int inL,int inR) {
    if ( preL > preR )
    {
        t=NULL;
        return ;
    }
    t = new node();
    t->data = pr[preL];
    int index;
    for ( index = inL; index <= inR; index++ ) {
        if ( in[index] == pr[preL] )break;
    }
    int numLeft = index - inL;
    create(t->l, preL+1, preL+numLeft, inL, index-1);
    create(t->r, preL+numLeft+1, preR, index+1, inR);
}

void post_display(const node *t)
{
    if(t==NULL)
        return ;
    post_display(t->l);
    post_display(t->r);
    printf("%c ",t->data);
}

int main()
{
    
    memset(pr,'\0',sizeof(pr));
    memset(in,'\0',sizeof(in));
    
    while(cin>>pr&&cin>>in)
    {
        node *tree=NULL;
        if(strlen(pr)==strlen(in))
        {
            create(tree,0,strlen(pr)-1,0,strlen(pr)-1);
            cout<<"build tree ok"<<endl;
        }
        //cout<<tree<<endl<<tree->l<<endl<<tree->r<<endl;
        post_display(tree);
        cout<<endl;
        memset(pr,'\0',sizeof(pr));
        memset(in,'\0',sizeof(in));
    }
    
    return 0;
}


/*
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 35;
char in[maxn];
char pre[maxn];
struct node {
    char data;
    node *lchild;
    node *rchild;
};

node *Create(int preL, int preR, int inL,int inR) {
    if ( preL > preR ) return NULL;
    node *root = new node();
    root->data = pre[preL];
    int index;
    for ( index = inL; index <= inR; index++ ) {
        if ( in[index] == pre[preL] )break;
    }
    int numLeft = index - inL;
    root->lchild = Create(preL+1, preL+numLeft, inL, index-1);
    root->rchild = Create(preL+numLeft+1, preR, index+1, inR);
    return root;
}


void PostOrderTraversal(node *root) {
    if ( root != NULL ) {
        PostOrderTraversal(root->lchild);
        PostOrderTraversal(root->rchild);
        cout << root->data << " ";
    }
}
int main() {
    int n;
    cin >> n;

    for ( int i = 0; i < n; i++ )
        cin >> pre[i];
    for ( int i = 0; i < n; i++ )
        cin >> in[i];
    node *root=NULL;
    root = Create(0,n-1,0,n-1);

    PostOrderTraversal(root);

    return 0;
}
*/
复制代码

 

 

 

tz@HZAU

2019/3/16

posted on   tuzhuo  阅读(660)  评论(0编辑  收藏  举报

编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2018-03-16 2017年蓝桥杯省赛A组c++第1题(走迷宫)
2018-03-16 2017年蓝桥杯省赛A组c++第6题(字符串匹配算法填空)
2018-03-16 2017年蓝桥杯省赛A组c++第5题(递归算法填空)
2018-03-16 2016年蓝桥杯省赛A组c++第9题(逆序串问题)
2018-03-16 2016年蓝桥杯省赛A组c++第7题(图论)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示