根据前序中序序列建树

118 阅读1分钟

在这里插入图片描述
本题的核心是根据前序和中序序列建树,显然这可以用递归去实现。
1 每次从前序序列中找到根节点存入树当中
2 遍历中序序列中找到该根结点位置,就可以划分出左右子树
3 先递归建左子树(也就是重复1、2),此时ipre=ipre+1,imid=0,n=i
4 再递归建右子树(也就是重复1、2),此时ipre=ipre+i+1,imid=imid+i+1,n=n-i-1(因为建完了左子树,所以需要跳过左子树的i个结点,结点个数也需要减掉左子树的i个结点)

#include<iostream>
using namespace std;
struct BiNode{
	char data;
	BiNode * lchild;
	BiNode * rchild;
};
//pre、mid分别存储前序和中序序列,ipre、imid分别是前序和中序开始遍历的位置,n为树的结点个数
BiNode *CreateByPreMid(char *pre,char *mid,int ipre,int imid,int n)
{
	if(n==0)
	return NULL;
	BiNode *p=new BiNode;
	p->data=pre[ipre];
	int i=0;
	while(pre[ipre]!=mid[imid+i]) i++;
	p->lchild=CreateByPreMid(pre,mid,ipre+1,imid,i);
	p->rchild=CreateByPreMid(pre,mid,ipre+i+1,imid+i+1,n-i-1);
	return p;
}
void PreOrder(BiNode *p)
{
	if(p){
		cout<<p->data;
		PreOrder(p->lchild);
		PreOrder(p->rchild);
	}
}
int Height(BiNode *p)
{
	if(p==NULL)
	return 0;
	int left,right;
	left=Height(p->lchild);
	right=Height(p->rchild);
	if(left>right)
	return left+1;
	else
	return right+1;
}
int main()
{
	char pre[55],mid[55];
	BiNode *root;
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>pre[i];
	}
	for(int i=0;i<n;i++)
	{
		cin>>mid[i];
	}
	
	root=CreateByPreMid(pre,mid,0,0,n);
	cout<<Height(root)<<endl;
	return 0;
}