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);
}