题目:https://pintia.cn/problem-sets/15/problems/838
输入数字N表示结点数,下一行分别输入先序遍历和中序遍历的结果,输出二叉树的高度;
思路;
(1)以先序遍历的第一个结点为根结点,在中序遍历找出根结点的位置,则在中序遍历中以此位置为划分,位置左边为根结点的左子树所含结点,位置右边为右子树所含结点;
(2) 分别对左子树和右子树的第一个结点作为根结点,重复上述操作;
例如:
已知一棵二叉树的先序遍历序列和中序遍历序列分别是abdgcefh,dgbaechf。
则第一次操作后可划分为: abdgcefh->a bdg cefh
dgbaechf->dgb a echf a的左子树有结点dgb,右子树有结点echf
然后对左子树bdg划分: bdg->b dg
dgb->dg b b的左子树有结点dg,无右子树
然后对右子树cefh划分:cefh->c efh
echf->e c hf c的左子树有结点e,右子树有结点hf
最后:
a
b c
d e f
g h
#include<iostream>
using namespace std;
typedef char type;
#define MAX 100
typedef struct Tree{
struct Tree *left,*right;
type data;
}Tree,*PTree;
PTree Create(char *p,char *m,int n){
if(!n) return NULL;
PTree pt=new Tree;
int i=0;
while(i<n){
if(m[i]==p[0]) break;
i++;
}
pt->data=p[0];
pt->left=Create(p+1,m,i);
pt->right=Create(p+i+1,m+i+1,n-1-i);
return pt;
}
int GetLength(PTree pt){
if(pt){
int m=GetLength(pt->left);
int n=GetLength(pt->right);
if(m>n) return ++m;
return ++n;
}
return 0;
}
int main(){
int n;
cin>>n;
type pre[51],mid[51];
cin>>pre>>mid;
PTree pt=Create(pre,mid,n);
cout<<GetLength(pt);
}
拓展:根据中序遍历和后序遍历还原二叉树
与上述大致相同,把后序遍历的最后一个结点作为根结点,之后的方法与上述相同。
例 后序遍历和中序遍历分别为: gdbehfca、dgbaechf
则 gdbehfca->gdb echf a
dgbaechf->dgb a echf 结点a的左子树有结点dgb,右子树有结点echf
gdb->gd b
dgb->dg b 结点b左子树有结点dg,右子树无结点