7-9 还原二叉树(25 point(s))
给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。
输入格式:
输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。
输出格式:
输出为一个整数,即该二叉树的高度。
输入样例:
9
ABDFGHIEC
FDHGIBEAC
输出样例:
5 根据前序和中序判断后序和根据中序和后序判断前序代码类似,只需稍微改动数组即可
#include <stdio.h> #include <string.h> #include <stdlib.h> int n; char pre[60],in[60]; 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){//如果长度为零说明这可子树建完了返回NULL 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]; n1++; } else if(in[i]!=pre[0]){//右子树的点,注意是else if,因为这个时候i是大于n1的 rin[n2] = in[i]; n2++; } } //分前序遍历序列,注意!这里从1开始循环,因为0号元素作为根 for(i = 1; i < n; i++){ if(i<(n1+1)){ 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;//最后一定要return这颗树,要不然怎么算高。。。 } 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(){ 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; }