二叉树的重建,已知先序中序求后序,已知后序中序求先序

二叉树的重建过程中必须存在中序序列 ,从先序或者后序中能确定二叉树的根节点,再从中序中确定左右根节点的左右子树,再将左右子树按照之前的方案进行处理;

一:先序序列+中序序列->后序序列

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
using namespace std;
typedef struct Node
{
    char    chValue;
    struct Node    *lChild;
    struct Node    *rChild;
} Node;
//重建二叉树
void Rebuild(char *pPreOrder , char *pInOrder , Node **pRoot , int nTreeLen)
{
    int  nLeftLen , nRightLen;
    char *pLeftEnd;
    Node *p;
    //边界条件检查
    if(!pPreOrder || !pInOrder || !pRoot)    return;
    if(!(p = (Node *)malloc(sizeof(Node))))    return;
    p->chValue = *pPreOrder;
    p->lChild = p->rChild = NULL;
    *pRoot = p;
    if(nTreeLen == 1)    return;
    //划分左右子数
    pLeftEnd = pInOrder;
    //cout<<"**"<<pLeftEnd<<endl;
    while(*pLeftEnd != *pPreOrder)
    {
         pLeftEnd++;
    }
    nLeftLen = (int)(pLeftEnd - pInOrder);
    nRightLen = nTreeLen - nLeftLen - 1;

    if(nLeftLen)    Rebuild(pPreOrder + 1 , pInOrder , &(p->lChild) , nLeftLen);
    if(nRightLen)   Rebuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen + 1 , &(p->rChild) , nRightLen);
}

//后序遍历
void PostOrder(Node *p)
{
    if(p)
    {
        PostOrder(p->lChild);
        PostOrder(p->rChild);
        printf("%c",p->chValue);
    }
}
int main(void)
{
    char PreOrder[32] , InOrder[32];
    Node *pTree;
    //输入先序和中序序列,求后序序列
    while(scanf("%s%s", PreOrder , InOrder) != EOF)
    {
        Rebuild(PreOrder , InOrder , &pTree , strlen(PreOrder));
        PostOrder(pTree);
        printf("\n");
    }
    return 0;
}
二:后 序序列+中序序列->前序序列

#include <iostream>
#include <string.h>
using namespace std;
struct tree
{
    char data;
    tree *left;
    tree *right;
};
tree *Rebuild(char *pos,char *in,int n,int m)
{
    tree *b;
    int k=0;
 char *p,*q,*maxp;
 int maxpost,maxin;
    if(n<=0)
    {
        return NULL;
    }
    maxpost=-1;
    for(p=in;p<in+n;p++)
    for(q=pos;q<pos+m;q++)
        if(*p==*q)
        {
            k=q-pos;
            if(k>maxpost)
            {
                maxpost=k;
                maxp=p;
                maxin=p-in;
            }
        }
        b=new tree;
        b->data=pos[maxpost];
    b->left=Rebuild(pos,in,maxin,m);
    b->right=Rebuild(pos,maxp+1,n-maxin-1,m);
    return b;
}
void pre(tree *b)
{
    if(b)
    {
        cout<<b->data;
        pre(b->left);

        pre(b->right);
    }
}
int main()
{
    char c1[1000],c2[1000];//输入后序加中序 求前序。
    while(cin>>c1>>c2)
    {
        tree *b;
        b=Rebuild(c1,c2,strlen(c1),strlen(c2));
        pre(b);
        cout<<endl;
    }
    return 0;
}
代码二:

#include<stdio.h>
#include<string.h>
void ReBuild(char *pre, char *in,char *post, int len)
{
	if(len>0)
	{
		int n =strchr(in,post[len-1])-in;
		ReBuild(pre+1,in,post,n);
		ReBuild(pre+n+1,in+n+1,post+n,len-n-1);
		pre[0]=post[len-1];
	}
}
int main()
{
	char pre[30],in[30],post[30];
	int len;
	while(~scanf("%s%s",post,in))
	{
		len=strlen(post);
		ReBuild(pre,in,post,len);
		pre[len]=0;
		puts(pre);
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值