基本思路:
1、先序遍历第一个结点作为根节点。
2、在中序遍历中查找根节点的位置,以此为界将中序遍历序列划分为左右两个序列(左、右子树)。
3、根据左、右子树在中序序列中的结点个数,将先序序列去掉根结点后的序列划分为左、右两个序列,它们分别为左、右子树的先序序列。
4、对左、右子树的先序序列和中序序列递归实施同样方法,直到左、右子树为空。
#include <stdio.h>
#include <stdlib.h>
typedef struct TNode
{
int data;
struct TNode *lchild,*rchild;
} TNode,*PTNode;
//先序遍历输出二叉树
void print(PTNode root)
{
PTNode ptnode = root;
if(ptnode!=NULL)
{
printf("%d ",ptnode->data);
print(ptnode->lchild);
print(ptnode->rchild);
}
}
//利用先序中序遍历重构二叉树
PTNode rebuild(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder)
{
int rootvalue = startPreorder[0];
PTNode root = (PTNode)malloc(sizeof(TNode));
root->data = rootvalue;
root->lchild = root->rchild = NULL;
if(startPreorder == endPreorder)
{
if(startInorder == endInorder && *startPreorder == *startInorder)
{
return root;
}
else
{
printf("input error!\n");
exit(-1);
}
}
//在中序遍历中找根节点的值
int *rootInorder = startInorder;
while(rootInorder<=endInorder && *rootInorder != rootvalue)
++rootInorder;
if(rootInorder == endInorder && *rootInorder != rootvalue)
{
printf("input error!\n");
exit(-1);
}
int leftLength = rootInorder-startInorder;
int *leftPreorderEnd = startPreorder+leftLength;
//构建左子树
if(leftLength>0)
{
root->lchild = rebuild(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
}
//构建右子树
if(leftLength<endPreorder-startPreorder)
{
root->rchild = rebuild(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
}
return root;
}
PTNode rebuildTree(int *preorder,int *inorder,int length)
{
if(preorder == NULL || inorder == NULL || length<=0)
return NULL;
return rebuild(preorder,preorder+length-1,inorder,inorder+length-1);
}
int main(int argc, char *argv[]) {
int pre[] = {1,2,3};
int in[] = {2,1,3};
PTNode root = rebuildTree(pre,in,sizeof(pre)/sizeof(pre[0]));
print(root);
return 0;
}