HDU 1710

分治思想。

主要思路:把先序序列的第一个数字当作一个根,在中序序列中寻找根,则中序序列中根前面的序列为根的左子树,后面的序列为右子树。

则再通过先序序列就可以找到当前根的左右节点,递归,将树还原,再后序遍历即可。


这套代码虽然一次性AC,但写的真的很累,太冗杂。引以为戒。

#include<cstdio>
struct BTnode
{
    int data;
    BTnode* lchild;
    BTnode* rchild;
}node[1001];

void recovery(BTnode* node,int* pre,int *mid,int preL,int preR,int midL,int midR)
{
    if(preR-preL==1&&midR-midL==1)
    {
        if(pre[preL]==mid[midL]) node[pre[preL]].rchild=&node[pre[preL+1]];
        else node[pre[preL]].lchild=&node[pre[preL+1]];
        return;
    }



    int next_mid,next_preR=preL;
    for(int i=midL;i<=midR;i++)
    {
        if(mid[i]==pre[preL])
        {
            next_mid=i;
            break;
        }

        for(int j=preL;j<=preR;j++)
        {
            if(pre[j]==mid[i]&&next_preR<j)
            {
                next_preR=j;
                break;
            }
        }
    }
    //printf("%d %d %d\n",next_mid,midR,next_preR);

    if(next_mid!=midL) node[pre[preL]].lchild=&node[pre[preL+1]];
    if(next_mid!=midR) node[pre[preL]].rchild=&node[pre[next_preR+1]];

    if(preL+1<next_preR&&midL<next_mid-1) recovery(node,pre,mid,preL+1,next_preR,midL,next_mid-1);
    if(next_preR+1<preR&&next_mid+1<midR) recovery(node,pre,mid,next_preR+1,preR,next_mid+1,midR);
}

bool first;
void visit(BTnode* node)
{
    if(node!=NULL)
    {
        visit(node->lchild);
        visit(node->rchild);
        if(first==1) {printf("%d",node->data); first=0;}
        else printf(" %d",node->data);
    }
}

void init()
{
    for(int i=1;i<=1000;i++)
    {
        node[i].data=i;
        node[i].lchild=NULL;
        node[i].rchild=NULL;
    }
}

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n==1) {int temp; scanf("%d",&temp); printf("%d\n",temp); continue;}
        init();
        int pre[n],mid[n];
        for(int i=0;i<n;i++)
            scanf("%d",&pre[i]);
        for(int i=0;i<n;i++)
            scanf("%d",&mid[i]);

        recovery(node,pre,mid,0,n-1,0,n-1);
        first=1;
        visit(&node[pre[0]]);
        printf("\n");

//        for(int i=1;i<=n;i++)
//        {
//            printf("%d\n",node[i].data);
//            BTnode* temp1=node[i].lchild;
//            BTnode* temp2=node[i].rchild;
//            if(temp1!=NULL) printf("%d\n",temp1->data);
//            else printf("0\n");
//            if(temp2!=NULL) printf("%d\n",temp2->data);
//            else printf("0\n");
//            printf("\n");
//        }
    }
    return 0;
}

7.22重写

#include<cstdio>
#include<cstring>
struct BT
{
    int l;
    int r;
    int val;

    BT(int a=0,int b=0,int c=0):l(a),r(b),val(c) {}
}tree[2000];
int Size=0;

int n,pre[2000],in[2000];

int findtree(int *P,int n1,int *I,int n2)
{
    int root=Size++;
    tree[root].val=P[0];
    tree[root].l=-1;
    tree[root].r=-1;

    if(n1==1&&n2==1)
        return root;

    int mid;
    for(mid=0;mid<n2;mid++)
    {
        if(I[mid]==P[0]) break;
    }

    if(mid!=0) tree[root].l=findtree(P+1,mid,I,mid);
    if(n1-mid-1!=0) tree[root].r=findtree(P+1+mid,n1-mid-1,I+1+mid,n2-mid-1);
    return root;
}

bool first=1;
void postorder(int root)
{
    if(tree[root].l!=-1) postorder(tree[root].l);
    if(tree[root].r!=-1) postorder(tree[root].r);
    if(first) {printf("%d",tree[root].val); first=0;}
    else printf(" %d",tree[root].val);
}

int main()
{
    while(~scanf("%d",&n))
    {
        Size=0;
        first=1;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&pre[i]);
        }

        for(int i=0;i<n;i++)
        {
            scanf("%d",&in[i]);
        }

        int root=findtree(pre,n,in,n);
        postorder(root);
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值