二叉树的前序遍历顺序为:中、左、右;中序遍历顺序为左、中、右。
(中为根节点)
前序遍历和中序遍历的对应关系如下图(左边前序遍历,右边中序遍历):
M:根节点,L:左子树,R:右子树
这个图非常重要,写迭代的时候,脑子里有这个图,就不会出错。
代码如下:
class TreeNode{
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
val = x;
}
}
public class tree {
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
if (pre == null || in == null) {
return null;
}
int pEnd = pre.length;
int iEnd = in.length;
// 这里的pEnd和iEnd长度需要减1
return btContract(pre, in, 0, pEnd - 1, 0, iEnd - 1);
//0。建立节点,判断是否为叶子节点
//1。找根节点
//2。划分左右子树
//3。递归(两个遍历序列都要注意范围)
//4。返回建立好的树
}
private TreeNode btContract(int[] pre, int[] in, int pStart, int pEnd, int iStart, int iEnd) {
TreeNode tree = new TreeNode(pre[pStart]);
tree.left = null;
tree.right = null;
if (pStart == pEnd || iStart == iEnd) {
return tree;
}
int root = 0;
for (root = iStart; root < iEnd; root++) {
if (in[root] == pre[pStart])
break;
}
int leftLength = root - iStart;
int rightLength = iEnd - root;
if (leftLength > 0) {
tree.left = btContract(pre, in, pStart + 1, pStart + leftLength, iStart, root - 1);
}
if (rightLength > 0) {
tree.right = btContract(pre, in, pStart + leftLength + 1, pEnd, root + 1, iEnd);
}
return tree;
}
}
数组的边界问题上非常容易出错,return btContract(pre, in, 0, pEnd - 1, 0, iEnd - 1);
这里的边界值一定要记得减1。