题目
思路
前序遍历是先输出根节点,然后左节点,右节点
也就是说,第一个节点必定是根节点,后序会把左子树的点输出完再输出右子树
后序遍历是先输出完左子树的节点,输出根基点,再输出右节点
所以我们先在先序遍历这里确定根基点
然后在中序遍历中找到A的位置,于是我们可以确定A的左边全都是左子树节点,A的右边全都是右子树节点
由于是同一颗树,左数节点+根节点的数量应该是一样的
中序遍历的右边就是右子树,而前序遍历将指向A的节点指向E后面(刚好对应中序遍历A的上方)开始递归创建右子树
而左子树就是从画橙圈的部分继续遍历
什么时候终止?
设置一个变量n来记录还有多少节点没有放入这个树中即可,当n逐渐变小==0的时候返回递归
代码
#include<iostream>
#include<stack>
using namespace std;
struct dot
{
int data;
dot* lchild;
dot* rchild;
dot()
{
data = -1;
lchild = rchild = NULL;
}
void pre_print()
{
stack<dot*> s;
//先序遍历是根左右
//对应栈就是先放根,然后pop根,push右,push左
if(this)
s.push(this);
while(!s.empty())
{
dot* temp = s.top();
s.pop();
dot* store = temp->rchild;
if(store)
s.push(store);
store = temp->lchild;
if(store)
s.push(store);
cout << static_cast<char>(temp->data) << (s.empty() ? "\n" : " ");
}
}
int height()
{
if(!this)
return 0;
int n = 0;
int k = 0;
if(this->lchild)
{
int l = this->lchild->height() + 1;
if(l > k)
k = l;
}
if(this->rchild)
{
int r = this->rchild->height() + 1;
if(r > k)
k = r;
}
if(k > n)
n = k;
return n;
}
};
dot* create_bintree(dot* &root, char *pre, char *med, int n)//要传引用不然改不了
{
if(n == 0)
root = NULL;
else
{
int root_loc = 0;
while(pre[0] != med[root_loc])
root_loc++;
root = new dot;
root->data = med[root_loc];
create_bintree(root->lchild, pre + 1, med, root_loc);
create_bintree(root->rchild, pre + root_loc + 1, med + root_loc + 1, n - root_loc - 1 );
}
return root;
}
int main()
{
int n; char pre[100]; char med[100];
cin >> n >> pre >> med;
dot* root = new dot;
create_bintree(root,pre,med,n);
cout << root->height() + 1;
}