package tree.BinaryTree;
import java.util.Arrays;
/**
* 根据先序和中序还原一个二叉树
*
* @author yuzhiyun
*
*/
public class ReCreateBinaryTree {
public static void main(String[] args) {
// 先序
int[] preOrder = { 1,2,4,7,3,5,6,8 };
// 中序
int[] midOrder = { 4,7,2,1,5,3,8,6 };
/**
* 思路是这样的, preOrder第一个元素1就是根节点啦 遍历midOrder找到1,那么1前面的元素(4,7,2)都是
* 根节点的左子树啦,1后面的元素(5,3,8,6)都是根节点的右子数 当然我们可以得知根节点的左子树的节点数为3,右子树的节点数为4,
* 那么回到preOrder,我们知道1后面的3个元素(2,4,7)是根节点左子树的先序遍历
* 同样的回到midOrder,1前面的3个元素(4,7,2)是根节点左子树的中序遍历
* 这样的话,我们最终得到了左子树的先序遍历和中序遍历,由此可以再次得到该左子树的根节点是谁。
* 这样相当于本题的规模变小了,有了递归的性质,显然递归可以得到结果
*/
TreeNode root = createBinaryTree(preOrder, midOrder);
System.out.print("先序打印");
prePrintBinaryTree(root);
System.out.println("");
System.out.print("中序打印");
inPrintBinaryTree(root);
System.out.println("");
System.out.print("后序打印");
postPrintBinaryTree(root);
}
/**
* 后序打印二叉树,验证二叉树建立是否正确
*/
private static void postPrintBinaryTree(TreeNode root) {
// TODO Auto-generated method stub
if (root.leftChild != null)
postPrintBinaryTree(root.leftChild);
if (root.rightChild != null)
postPrintBinaryTree(root.rightChild);
System.out.print(root.value + " ");
}
/**
* 中序打印二叉树,验证二叉树建立是否正确
*/
private static void inPrintBinaryTree(TreeNode root) {
if (root.leftChild != null)
inPrintBinaryTree(root.leftChild);
System.out.print(root.value + " ");
if (root.rightChild != null)
inPrintBinaryTree(root.rightChild);
}
/**
* 先序打印二叉树,验证二叉树建立是否正确
*/
private static void prePrintBinaryTree(TreeNode root) {
System.out.print(root.value + " ");
if (root.leftChild != null)
prePrintBinaryTree(root.leftChild);
if (root.rightChild != null)
prePrintBinaryTree(root.rightChild);
}
/**
*
* @param pre
* 先序
* @param in
* 后序
* @return 二叉树的根节点
*/
public static TreeNode createBinaryTree(int[] pre, int[] in) {
if (pre.length == 0 || in.length == 0)
return null;
// 获得根节点
TreeNode root = new TreeNode();
root.value = pre[0];
// 获取根节点在中序遍历序列中的index
int rootIndex = getIndexOfArray(pre[0], in);
/**
* 计算leftChild
*/
// leftChild的先序遍历
int[] leftChildPreOrder = new int[rootIndex];
for (int i = 0; i < rootIndex; i++)
leftChildPreOrder[i] = pre[i + 1];
System.out.println("左孩子先序"+Arrays.toString(leftChildPreOrder));
// leftChild的中序遍历
int[] leftChildMidOrder = new int[rootIndex];
for (int j = 0; j < rootIndex; j++)
leftChildMidOrder[j] = in[j ];
System.out.println("左孩子中序"+Arrays.toString(leftChildMidOrder));
root.leftChild = createBinaryTree(leftChildPreOrder, leftChildMidOrder);
/**
* 计算rightChild
*/
// rightChild的先序遍历
int[] rightChildPreOrder = new int[in.length - rootIndex - 1];
for (int j = 0; j < rightChildPreOrder.length; j++)
rightChildPreOrder[j] = pre[j + rootIndex + 1];
// rightChild的中序遍历
int[] rightChildMidOrder = new int[in.length - rootIndex - 1];
for (int k = 0; k < rightChildMidOrder.length; k++)
rightChildMidOrder[k] = in[k + rootIndex + 1];
root.rightChild = createBinaryTree(rightChildPreOrder,
rightChildMidOrder);
// System.out.print(root.value + " ");
return root;
}
/**
* 获取key在数组中的下标
*
* @param i
* @return
*/
private static int getIndexOfArray(int key, int[] midOrder) {
for (int i = 0; i < midOrder.length; i++) {
if (key == midOrder[i])
return i;
}
return 0;
}
}
class TreeNode {
int value;
TreeNode leftChild;
TreeNode rightChild;
TreeNode() {
leftChild = null;
rightChild = null;
}
}
根据先序和中序还原(重建)一个二叉树
最新推荐文章于 2024-06-28 11:28:22 发布