7-23 还原二叉树 (25 point(s))
给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。
输入格式:
输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。
输出格式:
输出为一个整数,即该二叉树的高度。
输入样例:
9
ABDFGHIEC
FDHGIBEAC
输出样例:
5
代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
struct TNode
{
int Data;
struct TNode* Left;
struct TNode* Right;
};
typedef struct TNode* Tree;
//还原二叉树的函数
Tree restoreTree(char pre[], char in[], int n)
{
int i;
char lpre[60], rpre[60];
char lin[60], rin[60];
int n1 = 0, n2 = 0;//n1记录前序遍历序列的左子树长度n2则记录前序遍历序列的右子树长度
int m1 = 0, m2 = 0;//m1记录中序遍历序列的左子树长度m2记录中序遍历序列右子树长度
if (n == 0)
{
return NULL;
}
Tree T = (Tree)malloc(sizeof(struct TNode));
/*if (T == NULL) {
return NULL;//若内存满了,返回NULL;
}*/
T->Data = pre[0]; // 当前根节点
for (i = 0; i < n; i++)
{
if (i <= n1 && in[i] != pre[0])
{ //中序遍历被根节点分开的左子树的点
lin[n1++] = in[i];
}
else if (in[i] != pre[0])
{ //右子树的点,注意是else if,因为这个时候i是大于n1的
rin[n2++] = in[i];
}
}
//分前序遍历序列,注意!这里从1开始循环,因为0号元素作为根
for (i = 1; i < n; i++)
{
if (i<(n1 + 1)) // 这里n1+1是因为编号是从1开始的,共有n1个左子数
{
lpre[m1++] = pre[i];
//m1++;
}
else
{
rpre[m2++] = pre[i]; // 其余为右子数
//m2++;
}
}
T->Left = restoreTree(lpre, lin, n1);
T->Right = restoreTree(rpre, rin, n2);
return T;
}
int getHight(Tree BST) {//得到树的高度,已知左右树高,树高为max(左树高,右树高)+1;
int lh, rh;
if (BST == NULL)
{
return 0;
}
else {
lh = getHight(BST->Left);
rh = getHight(BST->Right);
return (lh>rh ? lh : rh) + 1;
}
}
int main()
{
int n;
char pre[60], in[60];
scanf("%d", &n);
scanf("%s", pre);
scanf("%s", in);
Tree BST = NULL;
BST = restoreTree(pre, in, n);//建树
int hight;
hight = getHight(BST);//求高
printf("%d\n", hight);//输出
return 0;
}