这题 浪费了不少时间。。不知道自己现在怎么了。。遇到文件 就总要逃避一下。。唉。。
总的来说非常经典的题了。。就是构建函数 那 尤其是都用指针 太经典了
/*
给出 两个数组 前序和中序 要建立二叉树 返回root节点。。
本来不难的题结果自己看了半天。。唉。。好久不写二叉树了。
*/
#include<iostream>
#include<cstdio>
#include<exception>
#include<cstdlib>
using namespace std;
struct BTNode
{
int data;
BTNode * leftchild;
BTNode * rightchild;
};
BTNode * Construct(int*,int * ,int *,int *);
BTNode * ConstructBT(int * preorder,int * inorder,int len)
{
if(preorder == NULL || inorder == NULL || len<=0)
return NULL;
return Construct(preorder,preorder+len-1,inorder,inorder+len-1);
}
//这个函数的参数非常重要 是四个指针,分别是目前要建立二叉树的前序的头和尾 中序的头和尾
BTNode * Construct(int * startpreorder,int * endpreorder ,int * startinorder, int * endinorder)
{
BTNode * root =new BTNode();
int value=startpreorder[0];//前序的第一个是根节点,完成初始化root节点
root->data=value;
root->leftchild=root->rightchild=NULL;
if(startpreorder==endpreorder)//说明只有一个节点 就是根节点了 直接返回
{
if(startinorder==endinorder && *startpreorder == *startinorder)
return root;
else
printf("Invalid input");
}
//找出root 在 中序中的位置
int * rootinorder = startinorder;
while(rootinorder <=endinorder && *rootinorder!=value)
rootinorder++;
if(rootinorder == endinorder && *rootinorder!=value)
printf("Invalid Input\n");
//leftlenth 是目前要创建的 左子数的节点个数
int leftlenth=rootinorder-startinorder;
//这个指针 是要构建的左子树 结束的地方,开始的地方是starpreorder+1 就是原来的根节点的下一个开始到找到中序那里的前一个结束
int * leftPreorderEnd =startpreorder+leftlenth;
if(leftlenth>0)//有左子树,继续 递归创建
{
root->leftchild=Construct(startpreorder+1,leftPreorderEnd,startinorder,rootinorder-1);
}
if(leftlenth<endpreorder-startpreorder)//左边的长度比总的小 也就是有右子树 继续创建
{
root->rightchild = Construct(leftPreorderEnd+1,endpreorder,rootinorder+1,endinorder);
}
return root;
}
int main()
{
freopen("/home/gl/in","r",stdin);
int n,A[20],B[20];
scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%d",&A[i]);
for(int i=0;i<n;++i)
scanf("%d",&B[i]);
//ConstructBT 返回 root
BTNode * root = ConstructBT(A,B,n);
printf("%d\n",root->data);
while(root!=NULL)
{
printf("%d\n",root->data);
root=root->leftchild;
}
return 0;
}