首先看一下这个二叉树的结构,回忆一下前序序列的输出方式(中前后),中序序列的输出方式(前中后),后序序列的输出方式(前后中)。
前中序列还原二叉树
此二叉树的前中序列如下所示,我们要做的就是通过这两个序列还原出二叉树来。
前序序列{ A B H F D E C K G}
中序序列{ H B D F A E K C G}
由于前序序列输出方式是中前后,因此前序序列的开头即是根节点root。再由于中序序列的输出方式是前中后,所以只要找到了根节点root,就可以把中序序列以根节点为线分成左子树段和右子树段。左子树段同样的也存在一个根节点,我们只需要在前序序列中往后取左子树段相同数量的节点,再通过前序序列的中前后规律,得出左子树段的根节点,再往下划分。右节点同理,每次分段时,取前序序列末尾的部分(长度与右子树段相等),即可得出右子树段的根节点。如此递归下去,即可得到还原的树。代码如下:
static Node getRoot(ArrayList<Node> inOrder, int begin1, int end1, ArrayList<Node> preOrder, int begin2, int end2) {
if (begin1 > end1 || begin2 > end2) {
return null;
}
Node root = preOrder.get(begin2);
for (int i = begin1; i <= end1; i++) {
if (inOrder.get(i).element.equals(root.element)) {
root.left = getRoot(inOrder, begin1, i - 1, preOrder, begin2 + 1, begin2 - begin1 + i);
root.right = getRoot(inOrder, i + 1, end1, preOrder, end2 - end1 + i + 1, end2);
}
}
return root;
}
后中节点还原二叉树
后序序列输出方式是前后中,因此可以仿造前中序列还原二叉树的方法来做,改变就是在分段时根节点要从后先取。
static Node getRoot(ArrayList<Node> postOrder, int begin1, int end1, ArrayList<Node> preOrder, int begin2, int end2) {
if (begin1 > end1 || begin2 > end2) {
return null;
}
Node root = postOrder.get(end2);
for (int i = begin1; i <= end1; i++) {
if (inOrder.get(i).element.equals(root.element)) {
root.left = getRoot(inOrder, begin1, i - 1, postOrder, begin2, end2 + i - end1 - 1);
root.right = getRoot(inOrder, i + 1, end1, postOrder, end2 + i - end1, end2 - 1);
}
}
return root;
}