本文共 5183 字,大约阅读时间需要 17 分钟。
题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列。分析:
前序遍历的第一个节点时根,在中序中找到这个根节点,然后左边就是左子树,右边就是右子树,这样就可以递归。
用数组来记录,然后每次还重新弄数组,把左子树复制过来,右子树复制过来,递归。
public TreeNode constructionOfTree(int[] pre, int[] in) { if (pre == null || pre.length == 0 || in == null || in.length == 0) { return null; } if (pre.length == 1 && in.length == 1) { return new TreeNode(pre[0]); } int len = pre.length; int root = pre[0]; TreeNode tree = new TreeNode(root); int del = -1; for (int i = 0; i < in.length; i++) { if (in[i] == root) { del = i; break; } } int right_length = in.length - del - 1; int[] left_pre = new int[del]; int[] left_in = new int[del]; int[] right_pre = new int[right_length]; int[] right_in = new int[right_length]; for (int i = 1; i < del + 1; i++) { left_pre[i - 1] = pre[i]; left_in[i - 1] = in[i - 1]; } for (int i = del + 1; i < pre.length; i++) { right_pre[i - del - 1] = pre[i]; right_in[i - del - 1] = in[i]; } tree.left = constructionOfTree(left_pre, left_in); tree.right = constructionOfTree(right_pre, right_in); return tree; }
下面这种我觉得好些,用记录长度的方式,不用重复建立数组。
/** * * @param preOrder 前序遍历数组 * @param inOrder 中序遍历数组 * @param length 数组长度 * @return 根结点 */ public static BinaryTreeNode Construct(int[] preOrder, int[] inOrder,int length){ if (preOrder == null || inOrder == null || length <= 0) { return null; } try { return ConstructCore(preOrder, 0, preOrder.length - 1, inOrder, 0,inOrder.length - 1); } catch (InvalidPutException e) { e.printStackTrace(); return null; } } /** * * @param PreOrder * 前序遍历序列 * @param startPreIndex * 前序序列开始位置 * @param endPreIndex * 前序序列结束位置 * @param InOrder * 中序遍历序列 * @param startInIndex * 中序序列开始位置 * @param endInIndex * 中序序列结束位置 * @return 根结点 * @throws InvalidPutException */ public static BinaryTreeNode ConstructCore(int[] preOrder,int startPreIndex, int endPreIndex, int[] inOrder,int startInIndex, int endInIndex) throws InvalidPutException { int rootValue = preOrder[startPreIndex]; System.out.println("rootValue = " + rootValue); BinaryTreeNode root = new BinaryTreeNode(rootValue); // 只有一个元素 if (startPreIndex == endPreIndex) { if (startInIndex == endInIndex && preOrder[startPreIndex] == inOrder[startInIndex]) { System.out.println("only one element"); return root; } else { throw new InvalidPutException(); } } // 在中序遍历中找到根结点的索引 int rootInIndex = startInIndex; while (rootInIndex <= endInIndex && inOrder[rootInIndex] != rootValue) { ++rootInIndex; } if (rootInIndex == endInIndex && inOrder[rootInIndex] != rootValue) { throw new InvalidPutException(); } int leftLength = rootInIndex - startInIndex; int leftPreOrderEndIndex = startPreIndex + leftLength; if (leftLength > 0) { // 构建左子树 root.leftNode = ConstructCore(preOrder, startPreIndex + 1, leftPreOrderEndIndex, inOrder, startInIndex, rootInIndex - 1); } if (leftLength < endPreIndex - startPreIndex) { // 右子树有元素,构建右子树 root.rightNode = ConstructCore(preOrder, leftPreOrderEndIndex + 1, endPreIndex, inOrder, rootInIndex + 1, endInIndex); } return root; } static class InvalidPutException extends Exception { private static final long serialVersionUID = 1L; } public static void printPreOrder(BinaryTreeNode root) { if (root == null) { return; } else { System.out.print(root.value + " "); } if (root.leftNode != null) { printPreOrder(root.leftNode); } if (root.rightNode != null) { printPreOrder(root.rightNode); } } public static void main(String[] args) throws Exception{ ConstructionOfTree test=new ConstructionOfTree(); int[] preOrder={ 1,2,4,7,3,5,6,8}; int[] inOrder={ 4,7,2,1,5,3,8,6}; printPreOrder(test.Construct(preOrder, inOrder, preOrder.length)); }
public class BinaryTreeNode { public int value; public BinaryTreeNode leftNode; public BinaryTreeNode rightNode; public BinaryTreeNode() { } public BinaryTreeNode(int value) { this.value = value; this.leftNode = null; this.rightNode = null; }}
转载地址:http://lkena.baihongyu.com/