P1827 [USACO3.4]美国血统 American Heritage

P1827 [USACO3.4]美国血统 American Heritage

由前序遍历 中序遍历求后序遍历。
主要方法是找根节点在中序遍历中的位置

char *p;
    p=(char *)malloc(sizeof(char)*N);
    cin>>p;
    char *i;
    int n=strlen(p);
    for(i=p;i<p+n;i++) 
    {
        if(*i=='5') break;
    }
    cout<<i-p;

输入12345时,i-p = 4。可见下标是从1开始的。所以下面的递归构造左孩子时,就可以直接用k,因为这时的k是根节点所在位置-1。后面的构造右子树的时候,n是总数下标从1开始,k代表前序的串长度,再减1是减去根节点占的一格

//由二叉树的前序遍历,中序遍历求二叉树的后序遍历
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1000;
typedef struct node{
    char data;
    struct node *lchild;
    struct node *rchild;
}BTNode;
char *pre,*in; 
BTNode *CreateTree(char *pre,char *in,int n)//pre先序遍历  in中序遍历 n个数
{
    if(n<=0) return NULL;
    BTNode *st;
    st = (BTNode *)malloc(sizeof(BTNode));
    st->data = *pre;
    char *p;
    for(p=in;p<in+n;p++)
    {
        if(*p==*pre) break;
    }
    //*p是当前的根节点
    int k = p - in;//k:根节点在中序遍历中的位置-1 (减去根节点所占的一格)
    st->lchild = CreateTree(pre+1,in,k);
    st->rchild = CreateTree(pre+k+1,p+1,n-k-1);
    return st;
}
void houxu(BTNode *bt)
{
    if(bt==NULL) return;
    houxu(bt->lchild);
    houxu(bt->rchild);
    cout<<bt->data;
}
int main()
{
    pre = (char *)malloc(sizeof(char)*N);
    in = (char *)malloc(sizeof(char)*N);
    cin>>in>>pre;  //半个小时,花在先输入中序遍历 后输入前序遍历
    BTNode *st;
    int n = strlen(in);
    st = CreateTree(pre,in,n); 
    houxu(st);
}

不建树的方法:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100;
char lson[N],rson[N];
int pivot=0;
string in,pre;
void dfs(int root,int l,int r)
{
    if(l>=r) return;
    if(root>l)
    {
        lson[root] = pre[++pivot];
        dfs(in.find(lson[root]),l,root-1);
    }
    if(root<r)
    {
        rson[root] = pre[++pivot];
        dfs(in.find(rson[root]),root+1,r);
    }
}
void houxu(int root)
{
    if(root<0||root>in.length()) return;
    houxu(in.find(lson[root]));
    houxu(in.find(rson[root]));
    cout<<in[root];
}
int main()
{
  
    cin>>in>>pre;
    int root = in.find(pre[0]);
    dfs(root,0,in.length());
    houxu(root);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值