题目:
输入某二叉树的前序遍历和中序遍历,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。
例如,前序遍历序列:{1,2,3,7,3,5,6,8}
中序遍历序列:{4,7,2,1,5,3,8,6}
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
typedef struct bTreenode{
struct bTreenode *lchild;
struct bTreenode *rchild;
int data;
}bTreenode;
void Print(bTreenode *head)
{
bTreenode *p = head;
if(p != NULL){
printf("%d ",p->data);
Print(p->lchild);
Print(p->rchild);
}
}
bTreenode * create(void)
{
bTreenode *node = (bTreenode *)malloc(sizeof(bTreenode));
if(NULL == node){
printf("malloc fail\n");
return NULL;
}
node->data = 0;
node->rchild = NULL;
node->lchild = NULL;
return node;
}
bTreenode *dowork(int *prestart, int *preend,
int *midstart, int *midend)
{
/*
pre 1 2 4 7 3 5 6 8
mid 4 7 2 1 5 3 8 6
*/
// 1.从pre中找出root,创建root节点
int root_value = prestart[0]; //把root的值保存
bTreenode *root = create(); //创建节点并赋值
root->data = root_value;
if(prestart == preend && midstart == midend) //递归终止条件
return root;
//2.然后在mid中找到root,给予标记,来区分左子树和右子树
int *rootindex = midstart;
while(*rootindex != root_value && rootindex <midend) //寻找mid中的root的位置
rootindex++;
int leftlength = rootindex - midstart; //左子树的长度
int *leftend = prestart + leftlength; //左子树的末尾位置
// 3.把左右子树进行递归返回给root的左右孩子
if(leftlength > 0){ //leftchild
root->lchild = dowork(prestart+1,leftend, midstart, rootindex-1);
}
if(leftlength < preend - prestart){ //rightchild
root->rchild = dowork(leftend + 1, preend, rootindex+1, midend);
}
return root;
}
bTreenode *reBuild(int *pre, int *mid, int len)
{
if(pre == NULL || mid == NULL || len < 1)
return NULL;
//执行函数
bTreenode *node = dowork(pre , pre+len-1, mid, mid+len-1);
return node;
}
void Free(bTreenode * root)
{
if(root == NULL)
return ;
if(root->lchild)
Free(root->lchild);
if(root->rchild)
Free(root->rchild);
printf("free: %d\n",root->data);
free(root);
}
int main()
{
int pre[8] = {1,2,4,7,3,5,6,8};
int mid[8] = {4,7,2,1,5,3,8,6};
bTreenode *head = NULL;
int len = sizeof(pre) / sizeof(int);
head = reBuild(pre, mid, len);
Print(head);
printf("\n");
Free(head);
return 0;
}
执行结果: