问: 给定一个数组,为一个平衡二叉树的中序遍历结果,试生成这个平衡二叉树
答: 大约可解答如下(忽略各种异常bug判定)
package com.xss.tree;
import com.xss.node.TreeNode;
import com.xss.visit.Visit;
import java.util.HashMap;
import java.util.Map;
/**
* 给定平衡二叉树的中序遍历结果, 生成该平衡二叉树
*/
public class MiddleVisitBinaryTreeGeneratorTest {
public static void main(String[] args) {
int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6, 7, 8};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6, 7};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5, 6};
// int[] middleResultArr = {0, 1, 2, 3, 4, 5};
// int[] middleResultArr = {0, 1, 2, 3, 4};
// int[] middleResultArr = {0, 1, 2, 3};
// int[] middleResultArr = {0, 1, 2};
// int[] middleResultArr = {0, 1};
// int[] middleResultArr = {0};
MiddleVisitBinaryTreeGeneratorTest generator = new MiddleVisitBinaryTreeGeneratorTest();
TreeNode node = generator.generatorTree(middleResultArr);
// 前序遍历
Visit.firstVisitRoot(node);
System.out.println();
// 中序遍历
Visit.middleVisitRoot(node);
System.out.println();
// 后序遍历
Visit.lastVisitRoot(node);
System.out.println();
}
private TreeNode generatorTree(int[] middleResultArr) {
Map<Integer, TreeNode> nodeMap = new HashMap<>(middleResultArr.length);
for (int i = 0; i < middleResultArr.length; i++) {
nodeMap.put(i, new TreeNode(middleResultArr[i]));
}
// 获取根节点所在下标
int rootIndex = getRootIndex(0, middleResultArr.length - 1);
TreeNode node = nodeMap.get(rootIndex);
// 左子树下标从0到rootIndex-1
node.left = buildBinaryTree(0, rootIndex - 1, nodeMap);
// 右子树下标从rootIndex+1到最后的节点
node.right = buildBinaryTree(rootIndex + 1, middleResultArr.length - 1, nodeMap);
return node;
}
private int getRootIndex(int from, int to) {
int n = 0, x = 1, length = to - from + 1;
while (length >= x) {
n++;
x *= 2;
}
if (length >= 3 * calculateFactorial(n - 2) - 1) {
// 最后一层的节点数 >= 该层半数节点数
return from - 1 + calculateFactorial(n - 1);
} else {
return to + 1 - calculateFactorial(n - 2);
}
}
/**
* 计算2的m次幂
*
* @param n 数字n(>=0)
* @return 计算结果
*/
private int calculateFactorial(int n) {
int x = 1;
for (int i = 0; i < n; i++) {
x *= 2;
}
return x;
}
private TreeNode buildBinaryTree(int from, int to, Map<Integer, TreeNode> nodeMap) {
if (from > to) {
return null;
} else if (from == to) {
return nodeMap.get(from);
} else {
// 计算子平衡二叉树的根的下标
int rootIndex = getRootIndex(from, to);
TreeNode node = nodeMap.get(rootIndex);
// 左子树下标为from 到 rootIndex - 1
node.left = buildBinaryTree(from, rootIndex - 1, nodeMap);
// 右子树下标为rootIndex + 1 到to
node.right = buildBinaryTree(rootIndex + 1, to, nodeMap);
return node;
}
}
}
package com.xss.node;
public class TreeNode {
/**
* 值
*/
private int value;
/**
* 左子树
*/
public TreeNode left;
/**
* 右子树
*/
public TreeNode right;
public TreeNode(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
package com.xss.visit;
import com.xss.node.TreeNode;
public class Visit {
public static void firstVisitRoot(TreeNode node) {
if (node == null) {
return;
}
System.out.print(node.getValue() + " ");
if (node.left != null) {
firstVisitRoot(node.left);
}
if (node.right != null) {
firstVisitRoot(node.right);
}
}
public static void middleVisitRoot(TreeNode node) {
if (node == null) {
return;
}
if (node.left != null) {
middleVisitRoot(node.left);
}
System.out.print(node.getValue() + " ");
if (node.right != null) {
middleVisitRoot(node.right);
}
}
public static void lastVisitRoot(TreeNode node) {
if (node == null) {
return;
}
if (node.left != null) {
lastVisitRoot(node.left);
}
if (node.right != null) {
lastVisitRoot(node.right);
}
System.out.print(node.getValue() + " ");
}
}