题目
输入一棵二叉树前序遍历和中序遍历的结果,请重建该二叉树。
注意:
- 二叉树中每个节点的值都互不相同;
- 输入的前序遍历和中序遍历一定合法;
数据范围
书中节点数量范围 [0,100][0,100]。
样哩
给定:
前序遍历是:[3, 9, 20, 15, 7]
中序遍历是:[9, 3, 15, 20, 7]
返回:[3, 9, 20, null, null, 15, 7, null, null, null, null]
返回的二叉树如下所示:
3
/ \
9 20
/ \
15 7
思路:
先理清用前序+中序得出二叉树的过程,再运用递归方法
找到每个子树的根节点,再分出左子树和右子树(用数组表示出来),然后运用递归建立root->left和root->right
tip:遍历数组为空的情况,返回NULL
代码
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
struct TreeNode* buildTree(int* preorder, int preorder_size, int* inorder, int inorder_size) {
if(preorder == NULL || inorder == NULL) return NULL;
if(preorder_size == 0 || inorder_size == 0) return NULL; //用以保证数组为空时输出NUll
int rootval = preorder[0];
struct TreeNode *root = (struct TreeNode *)malloc(sizeof(struct TreeNode *));
root->val=rootval;
int i=0,j=0;
int pos=0; //根节点在中序序列中的位置
if(preorder_size == 1) return root; //如果只剩一个结点,直接返回
//确定pos
for(i=0;i<inorder_size;i++)
{
if(*(inorder+i) == preorder[0])
{
pos=i;break;
}
}
int Left_pre[pos],Left_order[pos];
int Right_pre[preorder_size-pos-1],Right_order[preorder_size-pos-1];
int len1=0,len2=0;
//依次复制几个数组
for(i=0;i<pos;i++)
{
Left_pre[i]=preorder[i+1]; //不要根节点
Left_order[i]=inorder[i];
len1++;
}
for(i=pos+1,j=0;i<preorder_size;j++,i++)
{
Right_pre[j]=preorder[i];
Right_order[j]=inorder[i];
len2++;
}
if(pos>0)
root->left = buildTree(Left_pre,len1,Left_order,len1);
if(pos<inorder_size-1)
root->right = buildTree(Right_pre,len2,Right_order,len2);
return root;
}