相关结构和函数定义在二叉树
性质1:在一颗二叉树的先序遍历结果中,根节点是先序序列的第一个。
性质2:在一颗二叉树的先序遍历结果中,如果知道根节点,就可以根据根节点的位置,将中序序列划分成左子树和右子树。
知道了这两条性质,就可以根据先序遍历和中序遍历结果,重建一颗二叉树。
重建过程:
(1)根据先序序列,找到根节点
(2)在中序序列中找到根节点位置,以此划分左子树与右子树。左子树的根是当前根的左孩子,右子树的根是当前根的右孩子。
(3)重复(1)(2)在左子树和右子树中分别进行递归查找根节点。递归终止条件是先序序列长度小于0。
话不多说,上代码,结合示意图理解。
BitNode *rebuild(ElemType *pre, ElemType *in, int preL, int preR, int inL, int inR)
{
// 递归终止
if(preL > preR) return NULL;
BitNode *root = newBitNode(pre[preL]);
// root在中序序列中的位置用inK保存
int inK;
for(inK=inL; inK<=inR; inK++)
{
if(pre[preL] == in[inK]) break;
}
// 左子树的节点个数
int nL = inK - inL;
// 左子树的先序区间为[preL+1, preL+nL], 中序区间为[inL, inK-1]
// 返回左子树的根节点地址,赋给root左孩子
root->left = rebuild(pre, in, preL+1, preL+nL, inL, inK-1);
// 右子树的先序区间为[preL+nL+1, preR], 中序区间为[inK+1, inR]
// 返回右子树的根节点地址,赋给root右孩子
root->right = rebuild(pre, in, preL+nL+1, preR, inK+1, inR);
return root;
}
测试代码
void test2()
{
ElemType pre[] = {'A', 'B', 'D', 'G', 'C', 'E', 'F'};
ElemType in[] = {'D', 'G', 'B', 'A', 'E', 'C', 'F'};
BitNode *root = rebuild(pre, in, 0, sizeof(pre)/sizeof(ElemType)-1, 0, sizeof(in)/sizeof(ElemType)-1);
levelOrderTraverse(root);
}
运行结果
A B C D E F G