题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。
根据先序遍历和中序遍历还原二叉树的主要思想:
1、先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点。
2、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。
3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。
主要函数代码
//传递要一个指针,和一段数据域。指针指向这段区域的根结点
//然后分成两个区域递归调用该函数
int ReCreate(BiTree *t,int begin,int end)
{
int i;
int key;
if(begin>end){ //如果不在范围内,证明没有该结点,赋值空指针并退出。
*t = NULL;
return 1;
}
key = probuf[++count];
for(i = begin;i <= end;i++){
if(inbuf[i] == key)
break;
}
if(i>end){ //当输入的数组不能构成二叉树的时候,返回NO!
*t = NULL; //退出的时候,指针为空,否则销毁二叉树时,程序会崩溃
printf("NO!\n");
return 0;
}
(*t) = (BiTree)malloc(sizeof(BiNode));
(*t)->key = key;
int leftbegin = begin;
int leftend = i-1;
int rightbegin = i+1;
int rightend = end;
i = ReCreate(&((*t)->lchild),leftbegin,leftend);
if(!i){ //必须判断是否构建过程是吧,然后递归返回,并且还要对又指针进行赋值,悬空的话,销毁二叉树时会崩溃
(*t)->rchild = NULL;
return 0;
}
ReCreate(&((*t)->rchild),rightbegin,rightend);
if(!i)
return 0;
return 1;
}
主程序
#include <stdio.h>
#include <stdlib.h>
int *probuf;
int *inbuf;
int count = -1;
typedef struct BiNode{
int key;
struct BiNode *lchild,*rchild;
}BiNode,*BiTree;
int ReCreate(BiTree *t,int begin,int end);
void PreOrderTraverse(BiTree t);
void InOrderTraverse(BiTree t);
void DestoryTree(BiTree *t);
void PostOrderTraverse(BiTree t);
int main(void)
{
BiTree T = NULL;
int n;
while(scanf("%d",&n)){
probuf = (int *)malloc(n*sizeof(int));
inbuf = (int *)malloc(n*sizeof(int));
for(int i = 0;i<n;i++)
scanf("%d",probuf+i);
for(int i = 0;i<n;i++)
scanf("%d",inbuf+i);
int i = ReCreate(&T,0,n-1);
if(!i)
DestoryTree(&T);
PostOrderTraverse(T);
printf("\n");
free(probuf);
free(inbuf);
DestoryTree(&T);
count = -1;
}
return 0;
}
//传递要一个指针,和一段数据域。指针指向这段区域的根结点
//然后分成两个区域递归调用该函数
int ReCreate(BiTree *t,int begin,int end)
{
int i;
int key;
if(begin>end){ //如果不在范围内,证明没有该结点,赋值空指针并退出。
*t = NULL;
return 1;
}
key = probuf[++count];
for(i = begin;i <= end;i++){
if(inbuf[i] == key)
break;
}
if(i>end){ //当输入的数组不能构成二叉树的时候,返回NO!
*t = NULL; //退出的时候,指针为空,否则销毁二叉树时,程序会崩溃
printf("NO!\n");
return 0;
}
(*t) = (BiTree)malloc(sizeof(BiNode));
(*t)->key = key;
int leftbegin = begin;
int leftend = i-1;
int rightbegin = i+1;
int rightend = end;
i = ReCreate(&((*t)->lchild),leftbegin,leftend);
if(!i){ //必须判断是否构建过程是吧,然后递归返回,并且还要对又指针进行赋值,悬空的话,销毁二叉树时会崩溃
(*t)->rchild = NULL;
return 0;
}
ReCreate(&((*t)->rchild),rightbegin,rightend);
if(!i)
return 0;
return 1;
}
void PreOrderTraverse(BiTree t)
{
if(t){
printf("%d ",t->key);
PreOrderTraverse(t->lchild);
PreOrderTraverse(t->rchild);
}
}
void InOrderTraverse(BiTree t)
{
if(t){
InOrderTraverse(t->lchild);
printf("%d ",t->key);
InOrderTraverse(t->rchild);
}
}
void PostOrderTraverse(BiTree t)
{
if(t){
PostOrderTraverse(t->lchild);
PostOrderTraverse(t->rchild);
printf("%d ",t->key);
}
}
void DestoryTree(BiTree *t)
{
if(*t){
DestoryTree(&((*t)->lchild));
DestoryTree(&((*t)->rchild));
free(*t);
*t = NULL;
}
}