先序中序后序求二叉树
问题
给定一棵二叉树的先序序列(后序序列)和中序序列,要求重建这棵二叉树。
解法
由二叉树的性质可知,先序序列的第一个元素是当前二叉树的根节点,根节点将中序序列分为左子树和右子树。先序序列的第一个元素即为整棵二叉树的根节点,在中序序列中找到该元素,则中序中该元素左侧为左子树,右侧为右子树,依照左右子树个数又可将先序序列剩余元素进行划分,接着只要对左子树和右子树进行递归操作即可。
node* create(int preL, int preR, int inL, int inR)
{
if (preL > preR) // 递归边界,序列长度为0
return NULL;
node* root = new node;
root->data = pre[preL]; // 先序序列第一个元素为根节点
int k;
for (k = inL; k <= inR; k++) // 找到中序序列中的根节点
if (in[k] == pre[preL])
break;
int numLeft = k - inL; // 左子树长度
root->lchild = create(preL + 1, preL + numLeft, inL, k - 1); // 递归处理左子树
root->rchild = create(preL + numLeft + 1, preR, k + 1, inR); // 递归处理右子树
return root;
}
依次类推可以写出后序中序序列求二叉树:
node* create(int postL, int postR, int inL, int inR)
{
if (postL > postR) // 递归边界,序列长度为0
return NULL;
node* root = new node;
root->data = post[postR]; // 后序序列最后一个元素为根节点
int k;
for (k = inL; k <= inR; k++) // 找到中序序列中的根节点
if (in[k] == post[postR])
break;
int numLeft = k - inL; // 左子树长度
root->lchild = create(postL, postL + numLeft - 1, inL, k - 1); // 递归处理左子树
root->rchild = create(postL + numLeft, postR - 1, k + 1, inR); // 递归处理右子树
return root;
}