题目:
题目:输入某二叉树的前序和中序遍历结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4, 7, 2,1,5,3,8,6},则重建如下图所示的二叉树并输出它的头结点。
分析:
1. 前序遍历和中序遍历的过程要明白(根节点的输出次序,前序:根-左-右; 中序:左-根-右)
2. 对于每个节点都可理解为其有左子树和右子树,即使为空
3. 递归形式处理
代码实现 : 代码部分含有注释可自行理解
/**
* 根据前序遍历和中序遍历重新构建二叉树
*
* @param DLRList 前序遍历数组
* @param startDLR 前序数组的开始位置
* @param endDLR 前序数组的结束位置
* @param LDRList 中序遍历数组
* @param startLDR 中序数组的开始位置
* @param endLDR 中序数组的结束位置
* @return 返回当前二叉树的根节点
*/
private TreeNode getRoot(int[] DLRList, int startDLR, int endDLR,
int[] LDRList, int startLDR, int endLDR) {
if (DLRList == null || LDRList == null) {
// 如果前序数组和中序数组都不存在,则返回空
return null;
}
// 定义二叉树实体时value值设为了String,所以在这需要转换一下
TreeNode rootNode = new TreeNode(String.valueOf(DLRList[startDLR]));
// 定义左子树
TreeNode leftNode = null;
// 定义右子树
TreeNode rightNode = null;
if (startDLR == endDLR && startLDR == endLDR) {
/**
* 如果前序数组的开始位置等于结束位置并且中序数组的开始位置等于结束位置,
* 则直接返回这个节点即可(无其他的左子树或者右子树)
*/
return rootNode;
}
/**
* 遍历中序数组,起始位置为中序的起始位置(startLDR),得到当前节点在中序数组
* 中的位置,以便统计左子树节点数量和右子树节点数量
*/
int rootLocation = startLDR;
for (; rootLocation < LDRList.length; rootLocation++) {
/**
* 如果当前前序数组的第一个节点值等于中序数组中的某一值
* 则判定当前位置rootLocation即为中序中根节点的位置
*/
if (DLRList[startDLR] == LDRList[rootLocation]) {
break;
}
}
// 根据中序数组中的节点位置计算,当前节点的左子树的数量
int leftLength = rootLocation - startLDR;
// 根据中序数组中的节点位置计算,当前节点的右子树的数量
int rightLenth = endLDR - rootLocation;
if (leftLength > 0) {
/**
* 如果有左子树,则进入递归模式
* 注意的是前序数组和中序数组不变,变化的是各个数组的起始位置
* 前序数组: DLRList, 开始位置 startDLR + 1,
* 结束位置:(前序数组中左子树结束位置)startDLR + leftLength
* 中序数组:LDRList, 开始位置 startLDR,
* 结束位置:(中序中左子树的结束位置) rootLocation - 1
*/
leftNode = getRoot(DLRList, startDLR + 1, startDLR + leftLength,
LDRList, startLDR, rootLocation - 1);
rootNode.setLeft(leftNode);
}
if (rightLenth > 0) {
/**
* 如果有右子树,则进入递归模式
* 注意的是前序数组和中序数组不变,变化的是各个数组的起始位置
* 前序数组: DLRList,
* 开始位置:(前序中右子树的开始位置) startDLR + leftLength + 1,
* 结束位置:(前序数组中的末尾位置)endDLR
* 中序数组:LDRList,
* 开始位置:(中序中右子树的开始位置)rootLocation + 1,
* 结束位置:(中序中右子树的结束位置) endLDR
*/
rightNode = getRoot(DLRList, startDLR + leftLength + 1, endDLR,
LDRList, rootLocation + 1, endLDR);
rootNode.setRight(rightNode);
}
// 返回生成的节点
return rootNode;
}